Dubbo 快速入門屠列,記錄下
概要:
- Dubbo 快速入門
- Dubbo 常規(guī)配置說明
一倒堕、Dubbo 快速入門
Dubbo核心功能解釋
dubbo 阿里開源的一個SOA服務(wù)治理框架蹂随,從目前來看把它稱作是一個RPC遠(yuǎn)程調(diào)用框架更為貼切锹漱。單從RPC框架來說佩谷,功能較完善,支持多種傳輸和序列化方案双抽。所以想必大家已經(jīng)知道他的核心功能了:就是遠(yuǎn)程調(diào)用
百框。
快速演示Dubbo的遠(yuǎn)程調(diào)用
實現(xiàn)步驟
- 創(chuàng)建服務(wù)端項目
- 引入dubbo 依賴
- 編寫服務(wù)端代碼
- 創(chuàng)建客戶端項目
- 引入dubbo 依賴
- 編寫客戶端調(diào)用代碼
dubbo 引入:【注解模式好像需要2.7】
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.2</version>
</dependency>
dubbo 默認(rèn)依懶:
客戶端代碼:
/**
* @author huey China.
* @Description : spring 整合 dubbo multicast
* @Date Created in 2018/11/26 下午23:02
*/
public class YoungClient {
// 基于 URL構(gòu)建遠(yuǎn)程服務(wù)
public UserService buildRemoteService(String remoteUrl) {
//引用配置
ReferenceConfig<UserService> referenceConfig = new ReferenceConfig();
referenceConfig.setInterface(UserService.class);
referenceConfig.setRegistry(new RegistryConfig("multicast://224.1.2.3:11111"));
referenceConfig.setUrl(remoteUrl);
//應(yīng)用
referenceConfig.setApplication(new ApplicationConfig("young-app"));
referenceConfig.setLoadbalance("roundrobin");
return referenceConfig.get();
}
public static void main(String[] args) throws IOException {
YoungClient client = new YoungClient();
UserService service = client.buildRemoteService(null);
int count = 0;
String cmd;
while (!"exist".equals(cmd = read())) {
System.out.println(
// 測試
service.getUser(1111)
);
}
}
private static String read() throws IOException {
byte[] b = new byte[1024];
LineNumberReader lineNumber = new LineNumberReader(
new InputStreamReader(System.in));
return lineNumber.readLine();
}
}
服務(wù)端代碼:
/**
* @author huey China.
* @Description : spring 整合 dubbo multicast
* @Date Created in 2018/11/26 下午23:02
*/
public class SimpleServer {
public void openService(int port)throws Exception {
// 服務(wù)配置
ServiceConfig<UserService> serviceConfig = new ServiceConfig();
// 設(shè)置服務(wù)接口
serviceConfig.setInterface(UserService.class);
// 設(shè)置開放的協(xié)議
serviceConfig.setProtocol(new ProtocolConfig("dubbo", port));
// 設(shè)置一個空的注冊中心
serviceConfig.setRegistry(new RegistryConfig("multicast://224.1.2.3:11111")); //網(wǎng)卡需要支持 走過虛擬網(wǎng)卡不支持的坑 設(shè)置host 本機名稱和物理ip映射
// 設(shè)置服務(wù)當(dāng)前所在應(yīng)用
serviceConfig.setApplication(new ApplicationConfig("simple-app"));
// 設(shè)置服務(wù)實現(xiàn)對象
UserServiceImpl ref = new UserServiceImpl(); serviceConfig.setRef(ref);
// 暴露服務(wù)
serviceConfig.export();
List<URL> list = serviceConfig.getExportedUrls();
ref.setPort(list.get(0).getPort());
System.out.println("服務(wù)已開啟 :" + list.get(0).getPort());
}
// 20880 20881
public static void main(String[] args) throws Exception {
new SimpleServer().openService(-1);
System.in.read();
}
}
運行驗證截圖
基于Dubbo實現(xiàn)服務(wù)集群:
在上一個例子中如多個服務(wù)的集群?即當(dāng)有多個服務(wù)同時提供的時候牍汹,客戶端該調(diào)用哪個?以什么方式進(jìn)行調(diào)用以實現(xiàn)負(fù)載均衡柬泽?
一個簡單的辦法是將多個服務(wù)的URL同時設(shè)置到客戶端并初始化對應(yīng)的服務(wù)實例慎菲,然后以輪詢的方式進(jìn)行調(diào)用。
但如果訪問增大锨并,需要擴容服務(wù)器數(shù)量露该,那么就必須增加配置重啟客戶端實例。顯然這不是我們愿意看到的第煮。Dubbo引入了服務(wù)注冊中的概念解幼,可以解決動態(tài)擴容的問題抑党。
演示基于注冊中心實現(xiàn)服集群:
- 修改服務(wù)端代碼,添加multicast 注冊中心撵摆。
- 修改客戶端代碼底靠,添加multicast 注冊中心。
- 觀察 多個服務(wù)時特铝,客戶端如何調(diào)用暑中。
- 觀察 動態(tài)增減服務(wù),客戶端的調(diào)用鲫剿。
# 服務(wù)端連接注冊中心
serviceConfig.setRegistry(new RegistryConfig("multicast://224.1.1.1:2222"));
# 客戶端連接注冊中心
referenceConfig.setRegistry(new RegistryConfig("multicast://224.1.1.1:2222"));
查看 基于**UDP** 占用的2222 端口
netstat -ano|findstr 2222
基于spring IOC維護Dubbo 實例
在前面兩個例子中 出現(xiàn)了,ApplicationConfig鳄逾、ReferenceConfig、RegistryConfig灵莲、com.alibaba.dubbo.config.ServiceConfig等實例 雕凹,很顯然不需要每次調(diào)用的時候都去創(chuàng)建該實例那就需要一個IOC 容器去管理這些實例,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:context="http://www.springframework.org/schema/context"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<!-- 應(yīng)用配置 ApplicationConfig -->
<dubbo:application name="simple-server"/>
<!--register 默認(rèn)等于true 把服務(wù)暴露到注冊中心去-->
<dubbo:registry address="zookeeper://192.168.59.2:2181"/>
<!-- 服務(wù)配置 ServiceConfig-->
<!-- service默認(rèn)值 protocol默認(rèn)值-->
<dubbo:provider protocol="dubbo" port="-1" timeout="6000"/>
<dubbo:service interface="huey.dubboserver.demo.UserService"
ref="userService" timeout="4000">
<dubbo:method name="getUser" timeout="2000"/>
</dubbo:service>
<bean id="userService" class="huey.dubboserver.demo.impl.UserServiceImpl"></bean>
</beans>
提供者服務(wù)暴露代碼:
ApplicationContext context = new ClassPathXmlApplicationContext("/spring-provide.xml");
((ClassPathXmlApplicationContext) context).start();
System.in.read();
消費者配置---------------------------------------
<?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.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<!-- 客戶端應(yīng)用名稱-->
<dubbo:application name="young-app"/>
<!--注冊中心地址 registryConfig-->
<dubbo:registry address="zookeeper://192.168.59.2:2181"></dubbo:registry>
<!--引用服務(wù) referenceConfig-->
<!--ID是必需項-->
<dubbo:consumer timeout="5000"></dubbo:consumer>
<dubbo:reference id="userService" interface="huey.dubboserver.demo.UserService"
timeout="3000">
</dubbo:reference>
</beans>
消費者調(diào)用代碼:
ApplicationContext context = new ClassPathXmlApplicationContext("/spring-consumer.xml");
UserService userService = context.getBean(UserService.class);
UserVo u = userService.getUser(1111);
System.out.println(u);
運行驗證截圖
二枚抵、Dubbo常規(guī)配置說明
Dubbo配置的整體說明:
| 標(biāo)簽 | 用途 | 解釋 |
|:----|:----|
| <dubbo:application/> | 公共 | 用于配置當(dāng)前應(yīng)用信息,不管該應(yīng)用是提供者還是消費者 |
| <dubbo:registry/> | 公共 | 用于配置連接注冊中心相關(guān)信息 |
| <dubbo:protocol/> | 服務(wù) | 用于配置提供服務(wù)的協(xié)議信息赠幕,協(xié)議由提供方指定俄精,消費方被動接受 |
| <dubbo:service/> | 服務(wù) | 用于暴露一個服務(wù),定義服務(wù)的元信息榕堰,一個服務(wù)可以用多個協(xié)議暴露竖慧,一個服務(wù)也可以注冊到多個注冊中心 |
| <dubbo:provider/> | 服務(wù) | 當(dāng) ProtocolConfig 和 ServiceConfig 某屬性沒有配置時,采用此缺省值逆屡,可選 |
| <dubbo:consumer/> | 引用 | 當(dāng) ReferenceConfig 某屬性沒有配置時圾旨,采用此缺省值,可選 |
| <dubbo:reference/> | 引用 | 用于創(chuàng)建一個遠(yuǎn)程服務(wù)代理魏蔗,一個引用可以指向多個注冊中心 |
| <dubbo:method/> | 公共 | 用于 ServiceConfig 和 ReferenceConfig 指定方法級的配置信息 |
| <dubbo:argument/> | 公共 | 用于指定方法參數(shù)配置 |
配置關(guān)系圖:
配置分類
所有配置項分為三大類砍的。
- 服務(wù)發(fā)現(xiàn):表示該配置項用于服務(wù)的注冊與發(fā)現(xiàn),目的是讓消費方找到提供方莺治。
- 服務(wù)治理:表示該配置項用于治理服務(wù)間的關(guān)系廓鞠,或為開發(fā)測試提供便利條件。
- 性能調(diào)優(yōu):表示該配置項用于調(diào)優(yōu)性能谣旁,不同的選項對性能會產(chǎn)生影響床佳。
dubbo 配置的一些套路:
先來看一個簡單配置
<dubbo:service interface="huey.dubboserver.demo.UserService" timeout="2000">
通過字面了解 timeout即服務(wù)的執(zhí)行超時時間。但當(dāng)服務(wù)執(zhí)行真正超時的時候 報的錯跟timeout并沒有半毛錢的關(guān)系榄审,其異常堆棧如下:
可以看到錯誤表達(dá)的意思是 因為Channel 關(guān)閉導(dǎo)致 無法返回 Response 消息砌们。
出現(xiàn)這情況的原因在于 雖然timeout 配置在服務(wù)端去是用在客戶端,其表示的是客戶端調(diào)用超時間,而非服務(wù)端方法的執(zhí)行超時浪感。當(dāng)我們?nèi)タ纯蛻舳说娜罩緯r候就能看到timeout異常了
類似這種配在服務(wù)端用在客戶端的配置還有很多昔头,如retries/ri?'tra?/(重試次數(shù))、async/??s??k/(是否異步)影兽、loadbalance(負(fù)載均衡)揭斧。。赢笨。等未蝌。
套路一:服務(wù)端配置客戶端來使用。
注:其參數(shù)傳遞機制是 服務(wù)端所有配置都會封裝到URL參數(shù)茧妒,在通過注冊中心傳遞到客戶端
如果需要暴露多個服務(wù)的時候萧吠,每個服務(wù)都要設(shè)置其超時時間,貌似有點繁瑣桐筏。Dubbo中可以通過 <dubbo:provider> 來實現(xiàn)服務(wù)端缺省配置纸型。它可以同時為 <dubbo:service> 和 <dubbo:protocol> 兩個標(biāo)簽提供缺省配置。如:
#相當(dāng)于每個服務(wù)提供者設(shè)置了超時時間 和重試次數(shù)
<dubbo:provider timeout="2000" retries="2"></dubbo:provider>
同樣客戶端也有缺省配置標(biāo)簽:<dubbo:consumer>梅忌,這些缺省設(shè)置可以配置多個 通過 <dubbo:service provider="providerId"> ,如果沒指定就用第一個狰腌。
、
套路二:<dubbo:provider>與<dubbo:service> 牧氮,<dubbo:consumer>與<dubbo:reference>傻傻分不清楚
在服務(wù)端配置timeout 之后 所有客戶端都會采用該方超時時間琼腔,其客戶端可以自定義超時時間嗎?通過 <dubbo:reference timeout="2000"> 可以設(shè)定或者在<dubbo:consumer timeout="2000"> 也可以設(shè)定 甚至可以設(shè)定到方法級別 <dubbo:method name="getUser" timeout="2000"/>踱葛。加上服務(wù)端的配置丹莲,超時總共有6處可以配置。如果6處都配置了不同的值尸诽,最后肯定只會有一個超時值生效甥材,其優(yōu)先級如下:
小提示:通過DefaultFuture的get 方法就可觀測到實際的超時設(shè)置。
com.alibaba.dubbo.remoting.exchange.support.DefaultFuture
套路三:同一屬性到處配置性含,優(yōu)先級要小心洲赵。
總結(jié)
如果本地有虛擬網(wǎng)卡 注意本地虛擬網(wǎng)卡的坑,可根據(jù)Dubbo源代碼追蹤商蕴,設(shè)置本地物理Ip和本機名稱(如hueydeMackBook.local)做映射
參考
官網(wǎng):http://dubbo.apache.org/zh-cn/docs/user/quick-start.html
GitBook:https://dubbo.gitbooks.io/dubbo-user-book/content/preface/background.html