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}")