目前處於實習期間,白天工作,網上自主學習。最近沒事逛了一下當前招聘網上的招聘要求,其中dubbo這個關鍵字出現的比較多,因此花了點時間學習了一番,在這寫寫自己的理解。
說起Dubbo,得先聊聊RPC,如果說互聯網架構師互聯網行業標配,那么RPC技術是分布式架構的基石
一、什么是RPC
RPC是指RPC協議:定義了rpc實現的規范,核心過程包括了客戶端和服務端的通訊協議,尋址,數據序列化/反序列化,http,dubbo-rpc都屬於rpc的一種協議
RPC框架:對上述核心過程進行了封裝,不需要開發人員自己去定義協議,實現序列化的細節工作,這樣的組件成為RPC框架。
常見RPC框架有thrift、GRpc、dubbo、motan
其中:客戶端如果想調用服務端
通訊協議:TCP/UDP
尋址:程序需要通過異性方式,才能知道服務端的IP+PORT號
序列化:數據在網絡中傳輸需要一定的格式
二、架構歷史
隨着網絡時代更新換代,其中所涉及的技術也是隨着時間日益變化,當然這也包含我們做項目時所利用到的框架。
1、單一架構。剛開始時,我們采用的是單一架構,這也是剛入門的小伙伴所鍾愛的架構,其項目中所涉及到的內容都統一部署在一起,無需要分層的思想。當然此僅僅局限於簡單的增刪改查 。
2、垂直架構。當數據訪問比較大時,簡單的單一架構已經遠遠無法滿足需求,垂直架構將應用拆分成互不相干的應用,以此來提高效率,這大大的增加前端頁面開發的效率,減少機器的負擔。
3、MVC架構。當項目數據較多時,維護成本也就增大,MVC模式就尤其顯得格外重要。MVC即model、view、controller,其將功能的各部分划分出來,同種功能放在同一包下。
4、分布式架構。垂直應用越來越多時,各個應用之間的交互不可避免。此時將核心業務抽取出來,形成獨立的服務,利用分布式緩存技術調用控制層來調用這些業務邏輯,以達到代碼重構。這就是所謂的SOA(面向服務架構)思想。如下訂單可以將其抽取出來,以達到服務共享。
三、什么是Dubbo
按我的理解,Dubbo是一個分布式框架,他出現的目的是為了提高性能和透明化的RPC遠程服務調用方案,SOA服務治理方案。其本質是一個服務調用,一個遠程調用的分布式框架。其核心部分包含為:
1、遠程通訊:提供多種基於長連接的NIO框架抽象封裝。
2、集群容錯:提供基於接口方法的透明遠程調用,包含軟負載均衡、失敗容錯、地址路由、動態配置等集群支持。
3、自動發現:基於注冊中心目錄服務,使服務消費方能動態查找服務提供方。
Dubbo局限
dubbo適合小數據量大並發的服務調用,以及消費者機器遠大於生產者機器數的情況,不適合傳輸大數據量的服務比如文件、視頻等,除非請求量很低。
四、dubbo框架流程圖

dubbo流程圖分為四大角色,依次為生產者,消費者,注冊中心以及監控中心。
生成者:提供服務,即提供方法接口。
注冊中心:生產者將每個服務的功能的注冊到注冊中心,每次有新服務的更新都會注冊到注冊中心,往其添加一個節點。其用Zk:(zookeeper,像樹)作為注冊中心,除此之外還可以用redis做,但是不推薦。
消費者:消費者與注冊中心相連接,稱之為訂閱。一旦有新的服務,注冊中心就會將結果返回通知消費者(zookeeper當中有一個事件通知,一旦節點有變化,就會通知客戶端),消費者一旦收到,就notify可以進行調用消費者中的服務(即調用接口)。
監控中心:做消費記錄,如監控消費者有沒有訂閱成功,以及有沒有記錄日志等。至於為什么redis也能作為注冊中心,是因為他里面也有一個watch監控。
五、就負載均衡而言,關於nginx和dubbo的區別
dubbo的負載均衡已經是服務層面的了,和nginx的負載均衡還在http請求層面完全不同。至於二者哪個優秀,當然沒辦法直接比較。
涉及到負載均衡就涉及到你的業務,根據業務來選擇才是最適合的。
dubbo具備了server注冊,發現、路由、負載均衡的功能,在所有實現了這些功能的服務治理組件中,個人覺得dubbo還是略微笨重了,因為它本身是按照j2EE范疇所制定的中規中矩的服務治理框架。
dubbo在服務發現這個地方做的更像一個dns,一個消費者需要知道哪里有這么一個服務,dubbo告訴他,然后他自己去調用。
而nginx在具備了以上功能,還有兩個最主要的功能是,1,維持盡可能多的連接。2,把每個連接的具體服務需求pass到真正的worker上。
但是這兩個功能,dubbo做不到第一個。
所以,結合你自己的業務來選擇用什么,nginx和dubbo在使用上說白了就是一個先后的關系而已。
總結:
nginx是橫在用戶的瀏覽器和自家的服務器之間。
dubbo是橫在自家的服務器和自家的服務器之間啊,是利用zookeeper的持久節點來保存信息。
六、快速入門
需要建立三個maven工程,分別為接口、消費者和生產者
1、先構建接口和生產者項目,並將接口的依賴注入到生產者pom文件(打開interface接口pom文件,將其依賴信息寫進provider的pom文件)

相關依賴代碼
<!--要使用會員接口,必須先引入其依賴 --> <dependency> <groupId>com.itmayie.du</groupId> <artifactId>Member-interface</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <!--生產者要引用到接口的方法,需要引入dubbo和zookeeper依賴--> <!-- 引入dubbo依賴 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.5.6</version> </dependency> <!-- 添加zookeeper客戶端依賴 --> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>0.1</version> </dependency>
2、會員接口提供定義接口方法

//會員服務 提供接口 public interface UserService { //使用用戶UserID查詢用戶信息 public String getUser(int id); }
3、生產者提供實現類
public class UserServiceImpl implements UserService{ public String getUser(int id) { System.out.println("會員服務接受訂單服務ID"+id); if(id==1){ return "yiling"; } if(id==2){ return "jiaxianseng"; } return "未找到..."; } }
4、生產者編寫spring配置文件,用於注入dubbo和zookeeper和實現類,暴露自己服務
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!-- 提供方應用信息,用於計算依賴關系 --> <dubbo:application name="provider"/> <!-- 使用zookeeper注冊中心暴露服務地址 --> <dubbo:registry address="zookeeper://192.168.174.133:2181"/> <!-- 使用dubbo協議在29014端口暴露服務 --> <dubbo:protocol name="dubbo" port="29014"/> <!-- 申明需要暴露的服務接口 --> <dubbo:service interface="com.dubbo.service.UserService" ref="userService"/> <!-- 具體實現bean --> <bean id="userService" class="com.dubbo.serviceImpl.UserServiceImpl"> </bean> </beans>
5、啟動zookeeper
[oracle@bogon bin]$ pwd /usr/java/zookeeper-3.4.12/bin [oracle@bogon bin]$ ./zkServer.sh start ZooKeeper JMX enabled by default Using config: /usr/java/zookeeper-3.4.12/bin/../conf/zoo.cfg Starting zookeeper ... already running as process 3579. [oracle@bogon bin]$ ./zkCli.sh [zk: localhost:2181(CONNECTED) 7] ls / [zookeeper]
6、測試連接zookeeper
//加載配置文件 ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("provider.xml"); applicationContext.start(); System.out.println("會員服務啟動成功"); //保證服務一直啟動,按任意鍵可以停止 System.in.read();
如果此時在開啟的zookeeper客戶端根節點看到新生成的節點說明連接成功
控制台:
log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment). log4j:WARN Please initialize the log4j system properly. 會員服務啟動成功
zookeeper:
[zk: localhost:2181(CONNECTED) 8] ls / [dubbo, zookeeper] [zk: localhost:2181(CONNECTED) 9] ls2 /dubbo [com.dubbo.service.UserService]
7、編寫消費者
1) pom文件引入接口、dubbo、zookeepre依賴
<dependency>
<groupId>Member-Interface</groupId>
<artifactId>Member-Interface</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- 引入dubbo依賴 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.5.6</version>
</dependency>
<!-- 添加zookeeper客戶端依賴 -->
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
</dependency>
2) 編寫消費者spring配置文件,接收生成者方法
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- 消費放應用名,用於計算依賴關系,不是匹配條件,不要與提供方一樣 -->
<dubbo:application name="consumer"/>
<!-- 使用multicast廣播注冊中心暴露發現服務地址 -->
<dubbo:registry protocol="zookeeper" address="zookeeper://192.168.174.133:2181"/>
<!-- 生成遠程服務代理,可以和本地bean一樣使用demoService -->
<dubbo:reference id="userService" interface="com.dubbo.service.UserService"/>
</beans>
3) 編寫調用測試類
public class OrderService { public static void main(String[] args) { ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("consumer.xml"); applicationContext.start(); System.out.println("訂單服務啟動成功.."); UserService userService=(UserService) applicationContext.getBean("userService"); System.out.println("訂單服務調用會員服務開始"); String result=userService.getUser(1); System.out.println("訂單服務調用會員服務結束..result"+result); System.in.read(); } }
注意:測試時要開啟zookeeper,先啟動生產者,再開啟消費者,順序不能錯
顯示結果:
消費者控制台:
log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment). log4j:WARN Please initialize the log4j system properly. 會員服務啟動成功 會員接受訂單,ID號為1
消費者控制台:
log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment). log4j:WARN Please initialize the log4j system properly. 訂單服務啟動 結果是yiling
七、關於dubbo所支持的協議
Dubbo協議、rmi協議、hession協議、http協議
八、關於dubbo-admin平台
dubbo-admin平台是用來管理duddo的客戶端,是一個可視化的dubbo平台界面,在其平台下,你可以調制各種參數。以下為dubbo-admin使用。
1、下載dubbo-admin
官網:dubbo-admin
2、將dubbo-admin.war進行解壓,將解壓的內容放在tomcat下的webapp目錄中的ROOT目錄(先清空原ROOT下的文件),這里我是放在的linux環境下的tomcat下
[root@bogon ROOT]# pwd /usr/java/tomcat/tomcat/webapps/ROOT [root@bogon ROOT]# ll 總用量 20 -rw-r--r--. 1 root root 101 3月 31 2015 crossdomain.xml drwxr-xr-x. 2 root root 54 6月 4 18:42 css -rw-r--r--. 1 root root 1406 3月 31 2015 favicon.ico drwxr-xr-x. 2 root root 4096 6月 4 18:42 images drwxr-xr-x. 2 root root 4096 6月 4 18:42 js drwxr-xr-x. 4 root root 51 6月 4 18:42 META-INF drwxr-xr-x. 2 root root 65 6月 4 18:41 SpryAssets drwxr-xr-x. 8 root root 4096 6月 4 18:41 WEB-INF
3、啟動tomcat
[root@bogon bin]# ./startup.sh
4、輸入域名(平常訪問tomcat)即可進入dubbo-admin界面

注意用戶名和密碼是根據dubbo.properties
[root@bogon ROOT]# cd WEB-INF/ [root@bogon WEB-INF]# tail -n 5 dubbo.properties dubbo.registry.address=zookeeper://127.0.0.1:2181 dubbo.admin.root.password=root dubbo.admin.guest.password=guest
官方界面如下:

九、關於Dubbo集群
模擬兩台提供相同服務的接口(集群),可以解決高並發的問題
步驟:
- 先更改生產者dubbo的端口號為29014,然后啟動生產者
- 再更改生產者dubbo的端口號為29015,然后啟動生產者
- 此時集群環境已經搭建好了,在dubbo控制平台中的服務治理中的提供者中可以看到兩個ip地址

十、關於dubbo的負載均衡
1、什么是負載均衡:
負載平衡也稱負載共享,是指對系統中的負載情況進行動態調整,以盡量消除或減少系統中各節點負載不均衡的現象。具體實現方法是將過載節點上的任務轉移到其他輕載節點上,盡可能實現系統各節點的負載平衡,從而提高系統的吞吐量。負載共享有利於統籌管理分布式系統中的各種資源,便於利用共享信息及其服務機制擴大系統的處理能力。
2、當出現集群的情況下,消費者是怎樣實現那台主機的選擇呢?
如同nginx一樣,dubbo也有負載均衡的策略
在集群負載均衡時,Dubbo提供了多種均衡策略,缺省為random隨機調用。
存在慢的提供者累積請求問題,比如:第二台機器很慢,但沒掛,當請求調到第二台時就卡在那,久而久之,所有請求都卡在調到第二台上。
解決辦法 :結合權重,把第二台機(性能低的)的權重設置低一點
做法
1) 為接口創建負載均衡策略
在服務治理中選擇負載均衡

2) 這里我們選擇的是隨機,也就是消費者會隨機選擇服務端口,當然可以控制生產者的權重問題來更改獲取幾率。
十一、關於dubbo容錯
當一個節點發生錯誤時,消費者會采取什么辦法?
Dubbo中自帶負載均衡容錯,即當一個節點發生錯誤(如20914節點關閉),由原來連接到20914節點的消費者會自動更改別的節點。
十二、當所有集群節點的dubbo服務都掛了,即發生了錯誤,消費者會怎么辦?
duboo通過keeopalived腳本監聽服務器,如果服務停止掉,自動幫你重啟,如果一直重啟失敗了,發送報警郵箱。
