天天看點

《一起學sentinel》一、一起搭建sentinel服務

一、概述

随着微服務的流行,服務和服務之間的穩定性變得越來越重要。Sentinel 以流量為切入點,從流量控制、熔斷降級、系統負載保護等多個次元保護服務的穩定性。

Sentinel 具有以下特征(來自官網概述):

  • 豐富的應用場景:Sentinel 承接了阿裡巴巴近 10 年的雙十一大促流量的核心場景,例如秒殺(即突發流量控制在系統容量可以承受的範圍)、消息削峰填谷、叢集流量控制、實時熔斷下遊不可用應用等。
  • 完備的實時監控:Sentinel 同時提供實時的監控功能。您可以在控制台中看到接入應用的單台機器秒級資料,甚至 500 台以下規模的叢集的彙總運作情況。
  • 廣泛的開源生态:Sentinel 提供開箱即用的與其它開源架構/庫的整合子產品,例如與 Spring Cloud、Dubbo、gRPC 的整合。您隻需要引入相應的依賴并進行簡單的配置即可快速地接入 Sentinel。
  • 完善的 SPI 擴充點:Sentinel 提供簡單易用、完善的 SPI 擴充接口。您可以通過實作擴充接口來快速地定制邏輯。例如定制規則管理、适配動态資料源等。

Sentinel 的主要特性:

《一起學sentinel》一、一起搭建sentinel服務

Sentinel 分為兩個部分:

  • 核心庫(Java 用戶端)不依賴任何架構/庫,能夠運作于所有 Java 運作時環境,同時對 Dubbo / Spring Cloud 等架構也有較好的支援。
  • 控制台(Dashboard)基于 Spring Boot 開發,打包後可以直接運作,不需要額外的 Tomcat 等應用容器。

二、概念簡述

1.核心術語

  • Resource

資源,特指需要限流的内容或對象

- 具體實作為`com.alibaba.csp.sentinel.slotchain.ResourceWrapper`

//資源:
protected final String name;//資源名稱

protected final EntryType entryType;//是入口流量還是出口流量

protected final int resourceType;//資源控制類型
/**
     public static final int COMMON = 0;
    public static final int COMMON_WEB = 1;
    public static final int COMMON_RPC = 2;
    public static final int COMMON_API_GATEWAY = 3;
    public static final int COMMON_DB_SQL = 4;
*/
//執行個體
//com.alibaba.csp.sentinel.slotchain.MethodResourceWrapper  方法資源包裝器
//com.alibaba.csp.sentinel.slotchain.StringResourceWrapper  字元串資源包裝器           
  • context

上下文,特指一個線程中的上下文,儲存目前調用的中繼資料

//包含以下元素

Node //Entry的統計

private final String name;//上下文名稱

private DefaultNode entranceNode;//目前調用樹的跟節點

private Entry curEntry;//目前調用節點

private String origin = "";//作為調用者或者觸發點,分别控制不同的調用者或者觸發點

private final boolean async;           
  • entry

入口,作為上下文中的連結項

  • 具體實作為

    com.alibaba.csp.sentinel.CtEntry

//連結上下鍊路
protected Entry parent = null;//父節點
protected Entry child = null;//子節點
protected ProcessorSlot<Object> chain;//核心插槽,後面會詳細講解
protected Context context;//鍊路上下文           
  • node

節點是用來儲存某個資源的各種實時統計資訊的,他是一個接口,通過通路節點,就可以擷取到對應資源的實時狀态,以此為依據進行限流和降級操作

  • FlowRule
    • com.alibaba.csp.sentinel.slots.block.flow.FlowRule

      可以了解為限流規則
      grade //代表示流控制的閥值類型,比如QPS或線程數
      
      private int strategy = RuleConstant.STRATEGY_DIRECT;
      //調用關系的政策
      //STRATEGY_DIRECT 用于直接流量控制(by origin);
      //STRATEGY_RELATE 用于相關流量控制(with relevant resource);
      //STRATEGY_CHAIN 用于鍊式流量控制(by entrance resource).
      
      controlBehavior//表示QPS成形行為(當QPS超過門檻值時對傳入請求的操作)。
                 

三、快速入手

1.1 公網 Demo

如果希望最快的了解 Sentinel 在做什麼,我們可以通過

Sentinel 新手指南

來運作一個例子,并且能在雲上控制台上看到最直覺的監控和流控效果等。

1.2 手動接入 Sentinel 以及控制台

下面的例子将展示應用如何三步接入 Sentinel。同時,Sentinel 也提供所見即所得的控制台,可以實時監控資源以及管理規則。

STEP 1. 在應用中引入Sentinel Jar包

如果應用使用 pom 工程,則在

pom.xml

檔案中加入以下代碼即可:

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-core</artifactId>
    <version>1.7.2</version>(最新的穩定版本)
</dependency>           
注意: 從 Sentinel 1.5.0 開始僅支援 JDK 1.7 或者以上版本。Sentinel 1.5.0 之前的版本最低支援 JDK 1.6。

如果您未使用依賴管理工具,請到

Maven Center Repository

直接下載下傳 JAR 包。

STEP 2. 定義資源

接下來,我們把需要控制流量的代碼用 Sentinel API

SphU.entry("HelloWorld")

entry.exit()

包圍起來即可。在下面的例子中,我們将

System.out.println("hello world");

這端代碼作為資源,用 API 包圍起來(埋點)。參考代碼如下:

//第一種方式SphU.entry
public static void main(String[] args) {
    initFlowRules();//(規則)
    while (true) {
        Entry entry = null;
        try {
        entry = SphU.entry("HelloWorld");
            /*您的業務邏輯 - 開始*/
            System.out.println("hello world");
            /*您的業務邏輯 - 結束*/
    } catch (BlockException e1) {
            /*流控邏輯處理 - 開始*/
        System.out.println("block!");
            /*流控邏輯處理 - 結束*/
    } finally {
       if (entry != null) {
           entry.exit();
       }
    }
    }
}


//第二種方式SphO.entry
public static void main(String[] args) {
    initFlowRules();//(規則)
    while (true) {
        if (SphO.entry("HelloWorld")) {
            try {
                /*您的業務邏輯 - 開始*/
                System.out.println("hello world");
                /*您的業務邏輯 - 結束*/
            } finally {
                SphO.exit();
            }
        }else {
            /*流控邏輯處理 - 開始*/
            System.out.println("block!");
            /*流控邏輯處理 - 結束*/
        }
    }
}           
  • SphU.entry

    方式會抛出異常
    • 如果沒有異常執行正确邏輯
    • 如果出現異常執行限流和熔斷邏輯
  • SphO.entry

    傳回的是一個boolean值
    • 如果true執行正确邏輯
    • 如果false執行限流和熔斷邏輯

完成以上兩步後,代碼端的改造就完成了。當然,也提供了

注解支援子產品

,可以以低侵入性的方式定義資源。

STEP 3. 定義規則

接下來,通過規則來指定允許該資源通過的請求次數,例如下面的代碼定義了資源

HelloWorld

每秒最多隻能通過 20 個請求。

private static void initFlowRules(){
    List<FlowRule> rules = new ArrayList<>();
    FlowRule rule = new FlowRule();
    rule.setResource("HelloWorld");
    rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
    // 設定QPS限制為20。
    rule.setCount(20);
    rules.add(rule);
    FlowRuleManager.loadRules(rules);
}           

完成上面 3 步,Sentinel 就能夠正常工作了。更多的資訊可以參考

使用文檔

STEP 4. 檢查效果

Demo 運作之後,我們可以在日志

~/logs/csp/${appName}-metrics.log.xxx

裡看到下面的輸出:

|--timestamp-|------date time----|-resource-|p |block|s |e|rt
1529998904000|2018-06-26 15:41:44|HelloWorld|20|0    |20|0|0
1529998905000|2018-06-26 15:41:45|HelloWorld|20|5579 |20|0|728
1529998906000|2018-06-26 15:41:46|HelloWorld|20|15698|20|0|0
1529998907000|2018-06-26 15:41:47|HelloWorld|20|19262|20|0|0
1529998908000|2018-06-26 15:41:48|HelloWorld|20|19502|20|0|0
1529998909000|2018-06-26 15:41:49|HelloWorld|20|18386|20|0|0           

其中

p

代表通過的請求,

block

代表被阻止的請求,

s

代表成功執行完成的請求個數,

e

代表使用者自定義的異常,

rt

代表平均響應時長。

可以看到,這個程式每秒穩定輸出 "hello world" 20 次,和規則中預先設定的門檻值是一樣的。

更詳細的說明可以參考:

如何使用

更多的例子可以參考:

Sentinel Examples

STEP 5. 啟動 Sentinel 控制台

您可以參考

Sentinel 控制台文檔

啟動控制台,可以實時監控各個資源的運作情況,并且可以實時地修改限流規則。