1. 程式人生 > >dubbo的常用配置(基於註解)

dubbo的常用配置(基於註解)

  之前記錄了基於springboot的dubbo入門案例,今天在此基礎上記錄dubbo官網介紹的常用屬性配置,dubbo讀取我們配置的屬性時是有優先順序的,優先順序如下圖:  

                  

  如圖所示,優先順序的屬性依次為虛擬機器引數>xml配置>dubbo.properties,虛擬機器引數即程式啟動之前我們通過-D配置的dubbo屬性,xml配置即我們專案中自己寫的xml檔案或者是springboot中的application.properties,當公共配置很簡單,沒有多註冊中心,多協議等情況,或者想多個 Spring 容器想共享配置的情況下可以用dubbo.properties作為預設配置;需要注意的是我這裡的測試用例都是寫在application.properties中,當然如果感覺不習慣,也可以跟普通maven專案一樣新建xml檔案,在xml中進行配置,只是不要忘了在springboot的啟動類中新增@ImportResource(locations="xml路徑")註解來引入就行,下面開始記錄dubbo的常用配置;

  一、啟動時檢查(check)

  預設情況下dubbo是開啟自動檢查的,即當專案啟動時會自動檢查其依賴的服務是否開啟,如果沒開是會阻止spring的初始化的,即check=true;我們可以將check置為false來關閉啟動時檢查,如我們在測試或者對其他服務沒有依賴的時候可以關閉檢查;在springboot中我們可以進行如下配置來關閉啟動時檢查:

  1、關閉某個服務的啟動檢查

  在引用該服務的@Reference註解上新增check=false,即@Reference(check = false)

  2、關閉所有服務的啟動時檢查

  在application.properties中新增dubbo.consumer.check=false

  二、超時(timeout,預設為1000),重試次數(retries)

  超時:當消費者呼叫提供者時由於網路等原因有可能會造成長時間拿不到響應,而請求還在不斷的發過來這就有可能造成執行緒阻塞,使用timeout設定超時時間當超過該時間就會丟擲異常;設定如下:

        當只針對某個服務時:@Reference(timeout=XXX)  

        當針對所有服務時:dubbo.consumer.timeout=XXX   

  重試次數:當呼叫失敗或超時後重新嘗試呼叫的次數,其值不包含第一次

     當只針對某個服務時:@Reference(retries=XXX)

        當針對所有服務時:dubbo.consumer.retries=XXX

  三、多版本(灰色釋出)

  當出現系統版本升級時,新版本有可能不夠穩定,這時候可以通過設定version來進行平滑的過渡,下面是dubbo官網的版本遷移步驟:

    在低壓力時間段,先升級一半提供者為新版本,再將所有消費者升級為新版本,然後將剩下的一半提供者升級為新版本

    而新舊版本我們可以通過version來定義,假設老版本的version=1.0.0新版本的version=2.0.0;

    老版本服務提供者:@Service(version='1.0.0')

    新版本服務提供者:@Service(version='2.0.0')

    老版本服務消費者:@Reference(version='1.0.0')

    新版本服務消費者:@Reference(version='2.0.0')

    這樣新舊版本就完美錯開,只會呼叫version對應的服務,如果呼叫的時候不需要區分版本號,則進行如下配置:@Reference(version='*'),這樣dubbo會預設在新老版本中隨機呼叫

  四、本地存根(stub)

    正常情況下,服務搭建成功後服務的實現一般都在服務端,但有時候我們可能需要在客戶端做些邏輯操作,比如引數驗證,快取處理以及呼叫失敗後偽造容錯資料的處理等等,這時候我們就需要用到dubbo的本地存根機制,他能在遠端服務呼叫前在客戶端進行相關的邏輯操作,具體步驟如下:

    1、在客戶端寫一個遠端呼叫服務的實現,並生成有參構造引數為遠端服務,程式碼如下:

package com.darling.boot.order.service;

import com.darling.pubIn.bean.User;
import com.darling.pubIn.service.UserService;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 *   @author 董琳琳
 *   @date 2018/10/10 15:11
 *   @description   userService的本地存根實現
 */
public class UserServiceStub implements UserService{
    private final UserService userService;

    /**
     * 有參構造 dubbo會自動將遠端Userservice注入進來
     * @param userService
     */
    public UserServiceStub(UserService userService) {
        this.userService = userService;
    }


    /**
     * 在遠端呼叫前可以進行判斷
     * @param userId
     * @return
     */
    @Override
    public List<User> getUserAddressList(String userId) {
        // 如果userId不為空則進行遠端呼叫 否則不調
        if(!StringUtils.isEmpty(userId)) {
            return userService.getUserAddressList(userId);
        }
        return null;
    }

    @Override
    public void sayHello() {

    }
}

   2、進行存根配置

    在客戶端呼叫遠端服務的註解上新增stub,值為我們客戶端實現的遠端服務類的全路徑名,如@Reference(stub = "com.darling.boot.order.service.UserServiceStub")

   五、負載均衡

    dubbo提供了四種負載均衡策略,分別是:

    1、Random LoadBalance 按權重的隨機負載均衡,也是dubbo預設的負載均衡策略

    2、RoundRobin LoadBalance 按權重的輪詢負載均衡,即在輪詢的基礎上添加了權重的策略

    3、LeastActive LoadBalance 最少活躍呼叫數,相同活躍數的隨機訪問,活躍數指呼叫前後的計數差即響應時間的長短;這種策略可以使響應慢的提供者收到的請求較少,大大提供系統性能

    4、ConsistentHash LoadBalance 一致性雜湊;相同引數的請求總是發到同一提供者

    負載均衡的配置:@Reference(loadbalance = "roundrobin"),loadbalance 的值即為四種負載均衡的名稱,全部小寫

  六、服務降級

    當伺服器壓力過大時,我們可以通過服務降級來使某些非關鍵服務的呼叫變得簡單,可以對其直接進行遮蔽,即客戶端不傳送請求直接返回null,也可以正常傳送請求當請求超時或不可達時再返回null;服務降級的相關配置可以直接在dubbo-admin的監控頁面進行配置;通常是基於消費者來配置的,在dubbo-admin找到對應的消費者想要降級的服務,點選其後面的遮蔽或容錯按鈕即可生效;其中,遮蔽按鈕點選表示放棄遠端呼叫直接返回空,而容錯按鈕點選表示繼續嘗試進行遠端呼叫當呼叫失敗時再返回空

  七、叢集容錯

    在叢集呼叫失敗時,Dubbo 提供了多種容錯方案,預設為 failover 重試。下面列舉dubbo支援的容錯策略:

    Failover Cluster:失敗自動切換,當出現失敗,重試其它伺服器。通常用於讀操作,但重試會帶來更長延遲。可通過 retries="XXX" 來設定重試次數(不含第一次)。

    Failfast Cluster:快速失敗,只發起一次呼叫,失敗立即報錯。通常用於非冪等性的寫操作,比如新增記錄。

    Failsafe Cluster:失敗安全,出現異常時,直接忽略。通常用於寫入審計日誌等操作。

    Failback Cluster:失敗自動恢復,後臺記錄失敗請求,定時重發。通常用於訊息通知操作。

    Forking Cluster:並行呼叫多個伺服器,只要一個成功即返回。通常用於實時性要求較高的讀操作,但需要浪費更多服務資源。可通過 forks="2" 來設定最大並行數。

    Broadcast Cluster:廣播呼叫所有提供者,逐個呼叫,任意一臺報錯則報錯 [2]。通常用於通知所有提供者更新快取或日誌等本地資源資訊。

     配置如下:@Reference(cluster = "failsafe")這裡表示使用失敗安全的容錯策略

    還有一種springcloud預設的容錯策略Hystrix;Hystrix旨在通過控制那些訪問遠端系統、服務和第三方庫的節點,從而對延遲和故障提供更強大的容錯能力。Hystrix具備擁有回退機制和斷路器功能的執行緒和訊號隔離,請求快取和請求打包,以及監控和配置等功能,下面介紹如何整合Hystrix:

    1、分別在提供者和消費者新增Hystrix依賴,或者直接在公共介面層新增,程式碼如下:

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>1.4.4.RELEASE</version>
</dependency>

    2、在提供者和消費者的啟動類上新增@EnableHystrix來啟用hystrix;

    3、在提供者需要容錯的方法上新增@HystrixCommand表示使用hystrix代理:

 @HystrixCommand // 開啟Hystrix代理
    @Override
    public List<User> getUserAddressList(String userId) {
        ArrayList list = new ArrayList();
        list.add(new User(3,"韋德3","男",36,"邁阿密"));
        list.add(new User(23,"詹姆斯23","男",34,"洛杉磯"));
        list.add(new User(24,"科比24","男",39,"洛杉磯"));
//        try {
//            Thread.sleep(5000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        return list;
    } 

    4、在消費者需要容錯的方法上新增@HystrixCommand,還可以給其新增屬性,表示調用出錯後處理錯誤的方法:

package com.darling.boot.order.service;

import com.alibaba.dubbo.config.annotation.Reference;
import com.darling.pubIn.bean.User;
import com.darling.pubIn.service.OrderService;
import com.darling.pubIn.service.UserService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 *   @author 董琳琳
 *   @date 2018/10/8 11:42
 *   @description
 */
@Service
public class OrderServiceimpl implements OrderService {

    @Reference(version = "*",stub = "com.darling.boot.order.service.UserServiceStub",cluster = "")
    UserService service;

    @HystrixCommand(fallbackMethod = "handlerException")
    @Override
    public List<User> initOrder(String userId) {
        return service.getUserAddressList(userId);
    }

    /**
     * 表示調用出錯後進行的處理,這裡沒有處理直接返回null
     * @param userId
     * @return
     */
    public List<User> handlerException(String userId) {
        return null;
    }
}

   在整合hystrix 時發現一個奇怪的現象,就是當你一旦在消費端整合hystrix 後,只要你傳送的請求沒有進行遠端呼叫,即使該請求沒有出錯並且正常返回了還是會進入fallbackMethod指定的容錯方法,百思不得其解, 準備後期去網上問問大神們

   由於時間關係,我對照官網就實現了以上幾種配置,還有許多其他配置沒有使用,希望在以後的工作中能有機會用到,到時候再回來記錄,這篇筆記的dubbo屬性配置有個值得注意的地方,就是我幾乎所有的配置都是在引用服務的註解@Reference上進行的,而dubbo支援多種配置,除了全域性配置還可以精確到給具體的類具體的方法進行配置,也可以給提供者和消費者進行配置,下面記錄dubbo的配置原則:

  dubbo推薦在Provider上儘量多配置Consumer端屬性,原因如下:

  1、作服務的提供者,比服務使用方更清楚服務效能引數,如呼叫的超時時間,合理的重試次數,等等

  2、在Provider配置後,Consumer不配置則會使用Provider的配置值,即Provider配置可以作為Consumer的預設值。否則,Consumer會使用Consumer端的全域性設定,這對於Provider不可控的,並且往往是不合理的

  配置優先順序: 方法級優先,介面級次之,全域性配置再次之;如果級別一樣,則消費方優先,提供方次之