分佈式架構-Dubbo框架(二):快速掌握Dubbo常規應用

概要:

  1. Dubbo 快速入門
  2. Dubbo 常規配置說明

一、Dubbo 快速入門

Dubbo核心功能解釋

dubbo 阿里開源的一個SOA服務治理框架,從目前來看把它稱作是一個RPC遠程調用框架更爲貼切。單從RPC框架來說,功能較完善,支持多種傳輸和序列化方案。所以想必大家已經知道他的核心功能了:就是遠程調用。

 

快速演示Dubbo的遠程調用

實現步驟

  1. 創建服務端項目
    1. 引入dubbo 依賴
    1. 編寫服務端代碼
  1. 創建客戶端項目
    1. 引入dubbo 依賴
    1. 編寫客戶端調用代碼

dubbo 引入:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>dubbo</artifactId>
    <version>2.6.2</version>
</dependency>

dubbo 默認依懶:

 

客戶端代碼:

static String remoteUrl = "dubbo://127.0.0.1:12345/tuling.dubbo.server.UserService";

// 構建遠程服務對象

public UserService buildRemoteService(String remoteUrl) {

    ApplicationConfig application = new ApplicationConfig();

    application.setName("young-app");

    ReferenceConfig<UserService> referenceConfig = new ReferenceConfig<>();

    referenceConfig.setApplication(application);

    referenceConfig.setInterface(UserService.class);

    referenceConfig.setUrl(remoteUrl);

    UserService userService = referenceConfig.get();

    return userService;

}

 

服務端代碼:

public void openServer(int port) {

    ApplicationConfig config = new ApplicationConfig();

    config.setName("simple-app");

    ProtocolConfig protocolConfig=new ProtocolConfig();

    protocolConfig.setName("dubbo");

    protocolConfig.setPort(port);

    protocolConfig.setThreads(20);

    ServiceConfig<UserService> serviceConfig=new ServiceConfig();

    serviceConfig.setApplication(config);

    serviceConfig.setProtocol(protocolConfig);

    serviceConfig.setRegistry(new RegistryConfig(RegistryConfig.NO_AVAILABLE));

    serviceConfig.setInterface(UserService.class);

    serviceConfig.setRef(new UserServiceImpl());

    serviceConfig.export();

}

基於Dubbo實現服務集羣:

在上一個例子中如多個服務的集羣?即當有多個服務同時提供的時候,客戶端該調用哪個?以什麼方式進行調用以實現負載均衡?

一個簡單的辦法是將多個服務的URL同時設置到客戶端並初始化對應的服務實例,然後以輪詢的方式進行調用。

 

但如果訪問增大,需要擴容服務器數量,那麼就必須增加配置重啓客戶端實例。顯然這不是我們願意看到的。Dubbo引入了服務註冊中的概念,可以解決動態擴容的問題。

 

 

演示基於註冊中心實現服集羣:

  1. 修改服務端代碼,添加multicast 註冊中心。
  1. 修改客戶端代碼,添加multicast 註冊中心。
  1. 觀察 多個服務時,客戶端如何調用。
  1. 觀察 動態增減服務,客戶端的調用。

 

# 服務端連接註冊中心

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 實例

在前面兩個例子中 出現了,ApplicationConfig、ReferenceConfig、RegistryConfig、com.alibaba.dubbo.config.ServiceConfig等實例 ,很顯然不需要每次調用的時候都去創建該實例那就需要一個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: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">

    <!-- 提供方應用信息,用於計算依賴關係 -->

    <dubbo:application name="simple-app"  />

    <!-- 使用multicast廣播註冊中心暴露服務地址 -->

    <dubbo:registry address="multicast://224.5.6.7:1234" />

    <!-- 用dubbo協議在20880端口暴露服務 -->

    <dubbo:protocol name="dubbo" port="20880" />

    <!-- 聲明需要暴露的服務接口 -->

    <dubbo:service interface="tuling.dubbo.server.UserService" ref="userService" />

    <!-- 和本地bean一樣實現服務 -->

    <bean id="userService" class="tuling.dubbo.server.impl.UserServiceImpl" />

</beans>

提供者服務暴露代碼:

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



    <dubbo:application name="young-app"/>

    <dubbo:registry address="multicast://224.5.6.7:1234"/>

    <dubbo:reference id="userService" interface="tuling.dubbo.server.UserService"/>

</beans>

消費者調用代碼:

ApplicationContext context = new ClassPathXmlApplicationContext("/spring-consumer.xml");

UserService userService = context.getBean(UserService.class);

UserVo u = userService.getUser(1111);

System.out.println(u);

二、Dubbo常規配置說明

Dubbo配置的整體說明:

標籤

用途

解釋

<dubbo:application/>

公共

用於配置當前應用信息,不管該應用是提供者還是消費者

<dubbo:registry/>

公共

用於配置連接註冊中心相關信息

<dubbo:protocol/>

服務

用於配置提供服務的協議信息,協議由提供方指定,消費方被動接受

<dubbo:service/>

服務

用於暴露一個服務,定義服務的元信息,一個服務可以用多個協議暴露,一個服務也可以註冊到多個註冊中心

<dubbo:provider/>

服務

當 ProtocolConfig 和 ServiceConfig 某屬性沒有配置時,採用此缺省值,可選

<dubbo:consumer/>

引用

當 ReferenceConfig 某屬性沒有配置時,採用此缺省值,可選

<dubbo:reference/>

引用

用於創建一個遠程服務代理,一個引用可以指向多個註冊中心

<dubbo:method/>

公共

用於 ServiceConfig 和 ReferenceConfig 指定方法級的配置信息

<dubbo:argument/>

公共

用於指定方法參數配置

配置關係圖:

 

配置分類

所有配置項分爲三大類。

  1. 服務發現:表示該配置項用於服務的註冊與發現,目的是讓消費方找到提供方。
  2. 服務治理:表示該配置項用於治理服務間的關係,或爲開發測試提供便利條件。
  3. 性能調優:表示該配置項用於調優性能,不同的選項對性能會產生影響。

dubbo 配置的一些套路:

先來看一個簡單配置

 <dubbo:service interface="tuling.dubbo.server.UserService"   timeout="2000">

通過字面瞭解 timeout即服務的執行超時時間。但當服務執行真正超時的時候 報的錯跟timeout並沒有半毛錢的關係,其異常堆棧如下:

 

可以看到錯誤表達的意思是 因爲Channel 關閉導致 無法返回 Response 消息。

出現這情況的原因在於 雖然timeout 配置在服務端去是用在客戶端,其表示的是客戶端調用超時間而非服務端方法的執行超時。當我們去看客戶端的日誌時候就能看到timeout異常了

 

 

類似這種配在服務端用在客戶端的配置還有很多,如retries/riː'traɪ/(重試次數)、async/əˈsɪŋk/(是否異步)、loadbalance(負載均衡)。。。等。

套路一:服務端配置客戶端來使用

注:其參數傳遞機制是 服務端所有配置都會封裝到URL參數,在通過註冊中心傳遞到客戶端

 

 如果需要暴露多個服務的時候,每個服務都要設置其超時時間,貌似有點繁瑣。Dubbo中可以通過  <dubbo:provider> 來實現服務端缺省配置。它可以同時爲 <dubbo:service> 和 <dubbo:protocol> 兩個標籤提供缺省配置。如:

#相當於每個服務提供者設置了超時時間 和重試次數

<dubbo:provider timeout="2000" retries="2"></dubbo:provider>

同樣客戶端也有缺省配置標籤:<dubbo:consumer>,這些缺省設置可以配置多個 通過 <dubbo:service provider="providerId"> ,如果沒指定就用第一個。

 

套路二:<dubbo:provider>與<dubbo:service> ,<dubbo:consumer>與<dubbo:reference>傻傻分不清楚 

 

   在服務端配置timeout 之後 所有客戶端都會採用該方超時時間,其客戶端可以自定義超時時間嗎?通過  <dubbo:reference timeout="2000"> 可以設定或者在<dubbo:consumer timeout="2000"> 也可以設定 甚至可以設定到方法級別 <dubbo:method name="getUser" timeout="2000"/>。加上服務端的配置,超時總共有6處可以配置。如果6處都配置了不同的值,最後肯定只會有一個超時值生效,其優先級如下:

 

 

小提示:通過DefaultFuture的get 方法就可觀測到實際的超時設置。

com.alibaba.dubbo.remoting.exchange.support.DefaultFuture

套路三:同一屬性到處配置,優先級要小心。

 

 

一般建議配置示例:

提供端:--------------------------- 

<dubbo:application name="demo-provider"/>

 <dubbo:registry protocol="redis" address="192.168.0.147:6379" check="true"/>

<dubbo:protocol name="dubbo" port="20880"/>

<dubbo:provider group="tuling.dubbo.demo"

                threadpool="fixed"

                threads="500"

                timeout="5000"

                retries="2"

/>

<dubbo:service interface="com.tuling.teach.service.DemoService"

               timeout="5000"

               retries="1"

               version="3.0.0"

               ref="demoService"/>

<bean id="demoService" class="com.tuling.teach.service.DemoServiceImpl"/>

 

消費端示例:--------------------

<dubbo:application name="demo-consumer"/>

<dubbo:registry protocol="redis" address="192.168.0.147:6379" check="true"/>

<dubbo:consumer timeout="5000" retries="2"

                group="tuling.dubbo.demo"

                version="1.0.0"/>

<dubbo:reference

        timeout="3000" retries="1"

        id="demoService"

        version="*"

        interface="com.tuling.teach.service.DemoService"/>

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章