Dubbo使用Sentinel來對服務進行降級與限流


一、Sentinel 是什么

Sentinel 是阿里中間件團隊開源的,面向分布式服務架構的輕量級流量控制產品,主要以流量為切入點,從流量控制、熔斷降級、系統負載保護等多個維度來幫助用戶保護服務的穩定性。 點此地址了解更多Sentinel

二、Sentinel 怎么用

Sentinel分為兩個部分:客戶端以及控制台。

  • 控制台用於管理限流,熔斷規則的發布與監控。
  • 客戶端則用於接收規則,並執行相關規則。

1. 下載Sentinel控制台

當前最新的release版本為1.4.0

https://github.com/alibaba/Sentinel/releases/tag/1.4.0

2. 運行Sentinel控制台

注意:啟動 Sentinel 控制台需要 JDK 版本為 1.8 及以上版本。

使用如下命令啟動控制台:

java -Dserver.port=8080 \
-Dcsp.sentinel.dashboard.server=localhost:8080 \
-Dproject.name=sentinel-dashboard  \
-jar sentinel-dashboard.jar

其中 -Dserver.port=8080 用於指定 Sentinel 控制台端口為 8080。

訪問http://localhost:8080查看控制台信息。

3. 客戶端Dubbo集成

使用時需引入以下模塊(以 Maven 為例):

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-dubbo-adapter</artifactId>
    <version>1.4.0</version>
</dependency>

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-transport-simple-http</artifactId>
    <version>1.4.0</version>
</dependency>

啟動時加入 JVM 參數

-Djava.net.preferIPv4Stack=true \
-Dcsp.sentinel.api.port=8720 \
-Dcsp.sentinel.dashboard.server=localhost:8787 \
-Dproject.name=example-customer

啟動項參數說明:

  • -Dcsp.sentinel.api.port 接受數據推薦的http端口
  • -Dcsp.sentinel.dashboard.server 指定控制台地址
  • -Dproject.name 指定控制台顯示的項目名稱

更詳細的信息可以參考啟動配置項

然后你可以愉快的打開控制台對你的服務進行限流,熔斷降級了。

三、現有的問題

  1. 規則的推送目前采用的是以http接口的形式進行數據處理,當發布規則時,需要采用遍歷所有的客戶端,以http的形式進行數據推送,此方式的問題在於服務部署數量越來越多,發布規則也就越來越慢,越來越困難。
  2. Sentinel的熔斷限流統計則是以異常發生數為依據,真正使用過程中還需要排除業務異常。
  3. 監控數據目前的做法是遍歷所有的客戶端采用http進行批量遠程讀取,並存儲入庫,且實時監控僅能查看5分鍾內的metric數據。
  4. Sentinel的啟動注入參數的方式太過原始。

四、如何改造

1. 關於Dashboard的數據推送問題的改造,思路可以考慮將數據傳遞到配置中心,利用配置中心來進行數據推送廣播。

  • 改造前:客戶端利用sentinel-transport-simple-http模塊暴露一個特定的端口,Sentinel Dashboard通過http的形式進行數據推送,客戶端接收后將規則保存在本地內存中。 改造前
  • 改造后:客戶端注冊到相關的注冊中心中,Sentinel Dashboard控制台將配置信息推送到配置中心,如nacos,zookeeper中,由配置中心去進行配置推送。 改造后

2. 關於Sentinel的業務異常問題,可以考慮采用類似於Hystrix的方法,HystrixBadRequestException被Hystrix認定為這是消費者自身的問題,而非提供者的服務不穩定,即我們常說的業務異常不被熔斷。

方法1:采用包裝異常的形式,將所有的異常包裝為統一的結構體,並設定異常狀態碼,例如業務異常都是400,服務異常是500。

public class Result<T> {

    /**
     * 狀態碼
     */
    private int code;

    /**
     * 消息
     */
    private String message;

    /**
     * 數據
     */
    private T result;

    // TODO 忽略get,set
}

Entry entry = null;
try {
    entry = SphU.entry(resourceName, entryType, 1, pjp.getArgs());
    Object result = pjp.proceed();

    // 核心判斷
    if (result instanceof Result && ((Result) result).getCode() == 500) {
        Tracer.trace(new RuntimeException(((Result) result).getMessage()));
    }
    return result;
} catch (BlockException ex) {
    return handleBlockException(pjp, annotation, ex);
} catch (Throwable ex) {
    Tracer.trace(ex);
    throw ex;
} finally {
    if (entry != null) {
        entry.exit();
    }
}

方法2:采用拋異常的形式,定義一個BussinessException業務異常。

Entry entry = null;
try {
    entry = SphU.entry(resourceName, entryType, 1, pjp.getArgs());
    return  pjp.proceed();
} catch (BlockException ex) {
    return handleBlockException(pjp, annotation, ex);
} catch (BussinessException ex) {
    // 核心處理
    throw ex;
} catch (Throwable ex) {
    Tracer.trace(ex);
    throw ex;
} finally {
    if (entry != null) {
        entry.exit();
    }
}

至於采用何種方式進行改造,見仁見智吧。

3. Sentinel監控問題,可以考慮采用CrateDB + Grafana/或者數據落地InfluxDB等方式。

相關鏈接參考:

4. Sentinel的啟動注入參數的方式太過原始,可以考慮使用spring-boot-starter的方式,采用自動化配置。

五、項目推薦

樓主自己改造了一個版本,目前已實現的功能如下:

  1. 新增dubbo的filter將異常包裝成統一返回體,將異常狀態碼定義為>=500的值(與HttpStatus相對應),修改SentinelResourceAspect實現,判斷返回的狀態碼是否為>=500,如果是則進行熔斷統計。
  2. 並新增sentinel-dubbo-starter,進行自動配置化。
  3. Sentinel Dashboard改造:控制台規則 -> 配置中心 -> 客戶端。

歡迎start,如有問題,歡迎指出,共同進步:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM