Dubbo原理
- 什么是RPC
- Dubbo框架
- 基本使用
- 基本底層原理
什么是RPC
維基百科定義:
遠程程序呼叫(英語:Remote Procedure Call,縮寫為 RPC)是一個計算機通信協議,該協議允許運行于一臺計算機的程式呼叫另一個地址空間(通常為一個開放網路的一臺計算機)的子程式,而程式員就像呼叫本地程式一樣,無需額外地為這個互動作用編程(無需關注細節),RPC是一種服務器-客戶端(Client/Server)模式,經典實作是一個通過發送請求-接受回應進行資訊互動的系統,如果涉及的軟體采用面向物件編程,那么遠程程序呼叫亦可稱作遠程呼叫或遠程方法呼叫,
RPC協議:只是定義資料傳輸格式和傳輸方式,是一種應用層協議,
傳輸方式:有基于HTTP傳輸資料的RPC Over HTTP,也有基于TCP的RPC Over TCP等,
資料格式:雙方協商定義,一般包括以下幾點:
1、類名
2、方法名
3、引數型別(用來確定具體執行的方法,有方法多載)
4、引數值

Dubbo框架
dubbo是一種高性能、輕量級的開源Java RPC框架(最新官網稱為服務框架),支持多種協議,默認使用dubbo協議,也可以使用HTTP協議等,
- 使用dubbo協議時,傳輸方式使用Netty;
- 使用HTTP協議時,傳輸方式使用Tomcat;
基本使用
Dubbo實作主要包括:服務提供者(provide)、服務消費者(Comsumer)、注冊中心、監控中心組成
服務提供者
1、定義服務介面、提供介面實作類
// 介面(對外暴露的服務)
public interface DemoService {
String sayHello(String name);
}
// 介面實作類
public class DemoServiceImpl implements DemoService {
public String sayHello(String name) {
return "Hello " + name;
}
}
2、配置對外暴露服務(dubbo-demo-provide.xml,也可以使用注解的方式實作)
<?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://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<!-- 定義應用名, 管理臺中會用到-->
<dubbo:application name="demo-provide" />
<!-- 使用zookeeper作為注冊中心,暴露服務 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181" />
<!-- 使用dubbo協議(可使用多種協議如:HTTP、rest),暴露埠為20880 server=Netty 指定傳輸方式-->
<!-- 針對整個應用,也可以針對服務指定協議 -->
<dubbo:protocol name="dubbo" port="20880" />
<!-- 宣告需要暴露的服務介面 interface:介面名字(也是服務名字) ref:介面對應的實作類 -->
<dubbo:service interface="org.apache.dubbo.demo.DemoService" ref="demoService" />
<!-- 和本地bean一樣實作服務,一般bean不在這配置,使用注解注入spring容器 -->
<bean id="demoService" class="org.apache.dubbo.demo.provider.DemoServiceImpl" />
</beans>
3、provide啟動類
@SpringBootApplication
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
服務消費者
1、消費者配置(dubbo-consumer.xml)
<?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://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<!-- 消費者應用名-->
<dubbo:application name="demo-consumer" />
<!-- 使用mzookeeper注冊中心發現暴露的服務地址 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181" />
<!-- 生成遠程服務代理,引入名字為org.apache.dubbo.demo.DemoService的服務,對應到本地的名字為demoService-->
<!-- 在Spring容器中可以通過demoService拿到這個服務-->
<dubbo:reference id="demoService" interface="org.apache.dubbo.demo.DemoService" />
</beans>
2、Consumer 啟動類
@SpringBootApplication
public class ConsumerApplication{
public static void main(String[] args) throws Exception {
SpringApplication.run(ConsumerApplication.class, args);
DemoService demoService = (DemoService)context.getBean("demoService"); // 獲取遠程服務代理
String hello = demoService.sayHello("world"); // 執行遠程方法
System.out.println( hello ); // 顯示呼叫結果
}
}
基本底層原理

Dubbo流程(粗略思路)
1、服務提供者提供介面、介面實作類(通過版本號區分多個實作類),對外暴露服務,通過共享注冊中心注冊服務(一般用zookeeper/redis),
為什么要使用共享注冊中心?
由于服務消費者和服務提供者是分別啟動兩個JVM(兩個行程),所以需要使用共享注冊中心,注冊服務形式-服務名:List
2、啟動Tomcat容器或Netty服務器
需要HTTP/Netty客戶端,用來接收請求,需要HTTP/Netty服務端用來處理請求,
3、服務消費者讀取用戶配置(共享注冊中心注冊的服務)
服務路徑每次從共享注冊中心獲取,消耗網路性能,所以先獲取存放至本地注冊中心快取,資料保持同步,
資料保持同步:
4、定義資料傳輸型別(Invocation物件,序列化)
構造Invocation物件:指定引數串列、方法、引數、地址、介面
5、dubbo生成介面代理類放入spring容器,指定呼叫服務,發送請求
指定服務:考慮支持集群,在代理類中,從注冊中心獲取到的服務路徑List有多個,使用負載均衡指定最終訪問的服務,
為什么使用zookeeper/Redis作為共享注冊中心?
在集群情況下會存在多個服務器,新增服務器注冊中心需要添加服務路徑,服務器掛了需要剔除服務路徑,集群發生變化時zookeeper可以通過監聽機制(Redis利用消費訂閱機制)保證資料同步,
6、服務提供者接收處理請求
其他部分細節
- 多版本實作:對于多個實作類,服務提供者通過版本號區分(拼在服務名后),Dubbo中實作類使用@Service(version = “callback”)標識,
- 支持多個協議以及協議切換:可以使用工廠模式根據配置協議名使用指定協議,
- 新增協議:使用SPI機制,
- 集群集群變更:利用心跳機制監控集群,zookeeper可通過臨時節點(Redis可通過過期時間節點)來實作心跳,這也是為什么注冊中心使用zookeeper/Redis而不使用MySQL等的原因之二,
- 容錯:服務呼叫失敗可能是服務端呼叫失敗也有可能是網路原因,Dubbo代理物件中捕獲例外,做相關的容錯處理,
- Mock:服務未實作完,沒必要進行網路請求,在發送之前可以做mock邏輯,
Dubbo功能及用法示例
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/256368.html
標籤:java
上一篇:學習Java例外,吃透這篇足夠
