一,學習背景 1. 前言 對於我們不管工作還是生活中,需要或者想去學習一些東西的時候,大致都考慮幾點: a) 我們為什麼需要學習這個東西? b) 這個東西是什麼? c) 這個東西能為我們做什麼? d) 如何去學? 結合以上幾點,我們一起學習下Dubbo這個框架! 2. 學習背景 互聯網的發展,網站應 ...
一,學習背景
1. 前言
對於我們不管工作還是生活中,需要或者想去學習一些東西的時候,大致都考慮幾點:
a) 我們為什麼需要學習這個東西?
b) 這個東西是什麼?
c) 這個東西能為我們做什麼?
d) 如何去學?
結合以上幾點,我們一起學習下Dubbo這個框架!
2. 學習背景
互聯網的發展,網站應用的規模不斷擴大,常規的垂直應用架構已無法應對,分散式服務架構以及流動計算架構勢在必行,Dubbo是一個分散式服務框架,在這種情況下誕生的。現在核心業務抽取出來,作為獨立的服務,使前端應用能更快速和穩定的響應。
3. Dubbo是什麼
Dubbo是Alibaba開源的分散式服務框架,它最大的特點是按照分層的方式來架構,使用這種方式可以使各個層之間解耦合(或者最大限度地松耦合)。從服務模型的角度來看,Dubbo採用的是一種非常簡單的模型,要麼是提供方提供服務,要麼是消費方消費服務,所以基於這一點可以抽象出服務提供方(Provider)和服務消費方(Consumer)兩個角色。關於註冊中心、協議支持、服務監控等內容
4. Dubbo能做什麼
當網站變大後,不可避免的需要拆分應用進行服務化(微服務),以提高開發效率,調優性能,節省關鍵競爭資源等。
當服務越來越多時,服務的URL地址信息就會爆炸式增長,配置管理變得非常困難,F5硬體負載均衡器的單點壓力也越來越大。
當進一步發展,服務間依賴關係變得錯蹤複雜,甚至分不清哪個應用要在哪個應用之前啟動,架構師都不能完整的描述應用的架構關係。
接著,服務的調用量越來越大,服務的容量問題就暴露出來,這個服務需要多少機器支撐?什麼時候該加機器?等等……
在遇到這些問題時,都可以用Dubbo來解決。
5. 如何去學習Dubbo
百度搜索Dubbo
a) 官網:http://dubbo.io/ 去查看關於dubbo的官方定義,瞭解這是個什麼東西。
b) Dubbo框架設計者的專訪:http://www.iteye.com/magazines/103看一下阿裡巴巴人士如何評價dubbo的。
c) Dubbo的入門使用:http://blog.csdn.net/congcong68/article/details/41113239
d) Dubbo框架的詳解與原理:http://shiyanjun.cn/archives/325.html看不懂就先會用。
二,開啟學習之路
1. Dubbo架構圖
總體設計架構:
基礎架構:
上圖中,藍色的表示與業務有交互,綠色的表示只對Dubbo內部交互。上述圖所描述的調用流程關係如下:
0. 服務容器負責啟動,載入,運行服務提供者,這個圖上沒標識出來,服務端啟動就是0.
1. 服務提供者在啟動時,向註冊中心註冊自己提供的服務。
2. 服務消費者在啟動時,向註冊中心訂閱自己所需的服務。
3. 註冊中心返回服務提供者地址列表給消費者,如果有變更,註冊中心將基於長連接推送變更數據給消費者。
4. 服務消費者,從提供者地址列表中,基於軟負載均衡演算法,選一臺提供者進行調用,如果調用失敗,再選另一臺調用。
5. 服務消費者和提供者,在記憶體中累計調用次數和調用時間,定時每分鐘發送一次統計數據到監控中心。
2. Dubbo與zookeeper
Dubbo為什麼要與zookeeper/Consule一起使用?
dubbo主要是一個分散式服務框架,致力於提供高性能和透明化的RPC遠程服務調用方案,以及SOA服務治理方案。簡單的說,dubbo就是個服務框架,如果沒有分散式的需求,其實是不需要用的.告別Web Service模式中的WSdl,以服務者與消費者的方式在dubbo上註冊.
zookeeper用來註冊服務和進行負載均衡,哪一個服務由哪一個機器來提供必需讓調用者知道,簡單來說就是ip地址和服務名稱的對應關係。zookeeper通過心跳機制可以檢測掛掉的機器並將掛掉機器的ip和服務對應關係從列表中刪除。
看圖識物:
上圖所示,假如我有四台伺服器,每台伺服器都提供相同的服務,如果我消費者去掉用的時候,肯定要在四個當中選擇某一個去調用,可是選擇哪一個就是一個難題,當然這就涉及到負載均衡問題了,或者我們在消費者這邊加代碼邏輯判斷達到負載均衡的效果。還有每次調用的時候都不知道要去掉哪個服務,都要查詢當前有哪些服務提供者,這是很耗開銷的,當服務提供越來越多的時候,越來越亂。
最終方案:
利用zookeeper生成的節點樹,伺服器提供者在啟動的時候,將提供的服務名稱和地址以節點的方式註冊都伺服器zookeeper伺服器配置中心,消費者通過伺服器配置中心獲取需要的服務名稱節點下的服務地址。因為znode有非持久節點的特性,伺服器可以動態的從服務配置中心一處,並且觸發消費者的watcher方法!!!
消費者只有在第一次調用的時候直接本地緩存伺服器列表信息,而不需要重新發起請求到伺服器配置中心區獲取相應 的伺服器列表,直到伺服器地址列表有變化(機器下線或者上線),變更之後消費者watcher進行服務地址的重新查詢。正是因為這種無中心化的結構,使得服務消費者在服務信息沒變更時候,幾乎不依賴配置中心,解決了負載均衡設備導致的單點故障的問題,大大減少了服務配置中心的壓力
3. Zookeeper的安裝
此處以windows環境下為例
註:linux安裝參考http://blog.csdn.net/lk10207160511/article/details/50526404
在apache的官方網站提供了好多鏡像下載地址,然後找到對應的版本,目前最新的是3.3.6
下載地址:
http://mirrors.cnnic.cn/apache/zookeeper/zookeeper-3.3.6/zookeeper-3.3.6.tar.gz
把下載的zookeeper的文件解壓到指定目錄
修改conf下增加一個zoo.cfg
內容如下:
# The number of milliseconds of eachtick 心跳間隔毫秒每次
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between
# sending a request and gettinganacknowledgement
syncLimit=5
# the directory where the snapshotisstored. //鏡像數據位置
dataDir=D:\\data\\zookeeper
#日誌位置
dataLogDir=D:\\logs\\zookeeper
# the port at which the clientswillconnect 客戶端連接的埠
clientPort=2181
註:如果啟動有報錯提示cfg文件有錯誤,可以用zoo_sample.cfg內內容替代也是可以的
進入到bin目錄,並且啟動zkServer.cmd,這個腳本中會啟動一個Java進程
這個時候zookeeper已經安裝成功了.
4. 配置dubbo-admin的管理頁面
下載dubbo-admin-2.4.1.war包,解壓到tomcat中。
如圖所示:
修改dubbo.properties文件,裡面指向Zookeeper ,使用的是Zookeeper 的註冊中心。
然後啟動tomcat服務,用戶名和密碼:root,並訪問服務,顯示登陸頁面,說明dubbo-admin部署成功,如圖所示:
目前我們還沒有註冊服務,所以內容都是空的。
5. 程式演示
現在我們來看個簡單的dubbo-demo項目,此項目只分解了兩個工程,一個服務提供者,一個消費者。此項目只適用於演示使用。因為,你在非分散式的項目上使用dubbo,多此一舉。
如圖:
6. 服務提供者
演示工程結構如下:
首先看下咱們的pom文件,引入Dubbo和Zookeeper的jar包.沒啥好說的。
然後我們寫自己的介面與實現,通常分散式設計下介面應該與實現分開,讓介面與bean單獨起工程模塊,以便服務提供者與消費者都可以調用。如果服務端有自己不暴漏的方法,可單寫介面類,也可中間加層,看業務而定。
重點看下我們dobbo配置
屬性說明:
dubbo:registry 標簽一些屬性的說明:
a) register是否向此註冊中心註冊服務,如果設為false,將只訂閱,不註冊。
b) check註冊中心不存在時,是否報錯。
c) subscribe是否向此註冊中心訂閱服務,如果設為false,將只註冊,不訂閱。
d) timeout註冊中心請求超時時間(毫秒)。
e) address可以Zookeeper集群配置,地址可以多個以逗號隔開等。
dubbo:service標簽的一些屬性說明:
a) interface服務介面的路徑
b) ref引用對應的實現類的Bean的ID
c) registry向指定註冊中心註冊,在多個註冊中心時使用,值為<dubbo:registry>的id屬性,多個註冊中心ID用逗號分隔,如果不想將該服務註冊到任何registry,可將值設為N/A
d) register 預設true ,該協議的服務是否註冊到註冊中心。
接下來我們啟動服務提供者服務,這裡我們常用的應該是啟動一個java程式,因為我們的工程中並沒有涉及web方面的業務,儘量不適用tomcat 啟動Web容器。
此時我們看下dubbo控制台,我們的服務已經註冊進zookeeper中,服務完成。
7. 服務消費者
我們寫一個消費者工程項目,結構如下:
Pom文件與服務者要引用的基本一樣,都是dubbo與zookeeper。
我們同樣寫一個介面類,與服務端的介面一致,此處如果服務端的介面分層出來,我們可以直接引用的,則不用寫此步了。
我們寫一個控制器代碼,調取介面。
配置我們dubbo配置文件,讓zookeeper給我們訂閱需要的服務,此處配置介面的訂閱也可使用註解形式,但對此,如果初期我們的項目用戶量不是特別大,我們不想使用分散式的時候,就不好拆除dubbo了。
配置說明:
dubbo:reference 的一些屬性的說明:
a) interface調用的服務介面
b) check 啟動時檢查提供者是否存在,true報錯,false忽略
c) registry 從指定註冊中心註冊獲取服務列表,在多個註冊中心時使用,值為<dubbo:registry>的id屬性,多個註冊中心ID用逗號分隔
d) loadbalance 負載均衡策略,可選值:random,roundrobin,leastactive,分別表示:隨機,輪循,最少活躍調用。此處可在zookeeper單獨配置,如下:
再次查看我們的dubbo控制台,發現消費者已經被註冊到zookeeper中。
消費者服務完成,我們來寫個測試。
8. Dubbo泛化調用(擴展篇)
Q:一個PHP工程師想調用某個Java介面,他並不能按照你約定,去寫一個個的介面,此時該怎麼辦?
A:Dubbo並不是跨語言的RPC框架,但並不是不能解決這個問題,使用dubbo的泛化調用,然後利用web返回json,這樣完成跨語言的調用。
總結:泛化調用,最最直接的表現就是服務消費者不需要有任何介面的實現,就能完成服務的調用。
泛化的使用比較簡單,服務提供者咱們還用上面工程,不需改變。泛化調用,肯定是調用方
去實現泛化。
看下我們的配置文件,如下:
有兩個地方需要註意一下,第一個是interface,其實該介面在消費者端並不存在,這是與往常寫的不一樣的地方,第二個地方需要註意的地方就是generic=”true”這樣的標簽,表示該介面支持泛型調用.
來看下我們怎麼用程式調用,如下一個測試:
從spring的上下文中讀到引用的介面bean,之後卻把它強轉為GenericService類,通用寫法。然後調用GenericService的$invoke的方法。
該方法有三個參數,第一個參數是你調用遠程介面的具體方法名,第二個參數是這個方法的入參的類型,最後一個參數是值。如下:
一個PHP程式員想要搭建一個簡單的web項目,可是你卻叫他依賴於spring的配置文件,他肯定不樂意,dubbo也幫你想到了,泛型調用,服務消費端可以不依賴spring的配置文件。如下:
小結:泛化調用可以方便用戶對dubbo服務消費者端的擴展,可以方便,豐富了服務消費者的調用方式,甚至可以做變相的Rest調用,這些都是可以的,不過,它的缺點也是很明顯的,參數傳遞複雜,不方便使用。但是這種方式是不能缺失的。