Dubbo
Dubbo介紹
Dubbo是輕量級,高性能的RPC架構,并不是一個微服務的全面解決方案,由Java語言開發。
RPC的介紹
- RPC: 遠端過程調用
-
在早期單機時代:IPC:單機裡各個程序間的互相通信
到了網絡時代:把IPC擴充到網絡上,就叫做了RPC。也就是通過socket、IO通信和傳輸
- 調用其他機器上的程式和調用本地程式一樣友善
常見的RPC架構:Dubbo、Montan(新浪,輕量級)、Thrift(Facebook,可以跨語言)
HTTP和RPC對比:
- HTTP和RPC都是用來通信的。但是HTTP有許多規定:請求頭組成、傳輸的要求等,效率較低。RPC效率較高,減少資源消耗。
- 傳輸效率: RPC方式可以自己進行定制,HTTP包含了許多無用的資訊,導緻效率低
- 性能消耗,主要是在于序列化和反序列化的耗時。 RPC采用二進制高效的傳輸,HTTP多采用JSON的格式進行傳輸,JSON轉為具體的對象比較耗時。
-
負載均衡:Dubbo在調用時發現如果有多個服務方可以進行負載均衡,采用随機 、輪詢等方式
HTTP可能會借助外部的元件。如nginx進行負載均衡,自身對這個能力比較欠缺。
Dubbo工作原理

角色
- Provider:服務的服務提供者
- Consumer:調用遠端服務的消費者
- Container:服務運作的容器
- Registry:服務注冊和發現的注冊中心
- Minitor:統計服務調用次數和時間的監控中心
調用關系
- 0:伺服器容器負責啟動、加載、運作服務提供者。
- 1:服務提供者在啟動後就可以向注冊中心暴露服務。
- 2:服務消費者在啟動後就可以向注冊中心訂閱想要的服務。
- 3:注冊中心向服務消費者傳回服務調用清單。
- 4:服務消費者基于負載均衡算法調用服務提供者的服務,這個服務提供者有可能是一個服務提供者清單,調用那個服務提供者就是根據負載均衡來調用了。
- 5:服務提供者和服務消費者定時将儲存在記憶體中的服務調用次數和服務調用時間推送給監控。
Dubbo支援的通信協定
1)Dubbo協定
dubbo://ip:端口
單一長連接配接,NIO異步通信,基于hessian作為序列化協定,适用傳輸資料量很小(每次請求在100kb以内),但是并發量很高
Dubbo預設協定采用單一長連接配接和NIO異步通訊,适合于小資料量大并發的服務調用,以及服務消費者機器數遠大于服務提供者機器數的情況
2)RMI協定
RMI協定采用JDK标準的java.rmi.*實作,采用阻塞式短連接配接和JDK标準序列化方式
走java二進制序列化,多個短連接配接,适合消費者和提供者數量差不多,适用于檔案的傳輸,一般較少用
3)Hessian協定
Hessian協定用于內建Hessian的服務,Hessian底層采用Http通訊,采用Servlet暴露服務,Dubbo預設内嵌Jetty作為伺服器實作
走Hessian序列化協定,多個短連接配接,适用于提供者數量比消費者數量還多,适用于檔案的傳輸,一般較少用
4)Http協定
采用Spring的HttpInvoker實作
走json序列化
5)webservice
基于CXF的frontend-simple和transports-http實作
走SOAP文本序列化
dubbo支援的序列化協定
是以dubbo實際基于不同的通信協定,支援hessian、java二進制序列化、json、SOAP文本序列化多種序列化協定。但是hessian是其預設的序列化協定。
Dubbo本地存根(Stub)
- 類似于Dubbo的靜态代理
- Dubbo會在用戶端生成一個代理,處理部分業務
- Stub必須有可傳入的Proxy的構造函數
流程:
簡單的調用
- 引入依賴
父pom檔案
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-bom</artifactId>
<version>${dubbo.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
</exclusion>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
producer和concumer的 pom檔案
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
</dependency>
<!-- Zookeeper dependencies -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper</artifactId>
<version>${dubbo.version}</version>
<type>pom</type>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
-
Dubbo和Zookeeper的簡單配置
concumer的properties配置檔案
demo.service.version=1.0.0
#dubbo協定
dubbo.protocol.name=dubbo
dubbo.protocol.port=-1
#dubbo注冊zookeeper
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.registry.file=${user.home}/dubbo-cache/dubbo.cache
producer的properties配置檔案在此基礎上還要加上一個Dubbo包掃描的配置
dubbo.scan.base-packages=com.liu.producer.service.impl
- 業務中producer的service實作類加@Service(version = "${demo.service.version}"),注意是Dubbo的service注解
- 業務中producer的service實作類注入依賴時加 @Reference(version = "${demo.service.version}")
@Reference(version = "${demo.service.version}")
CourseListService courseListService;