Sentinel的使用

概述

Sentinel譯為“哨兵”,顧名思義,面對您后臺的大量服務(wù)/微服務(wù),前置一個哨兵,但面對大量請求時,讓后臺服務(wù)有序被調(diào)用,但某些服務(wù)的不可用時,采用服務(wù)熔斷降級等措施,讓系統(tǒng)仍能平穩(wěn)運行,不至于造成系統(tǒng)雪崩,典型應(yīng)用場景:

  1. MQ中消息在某些時間段(比如行情交易的高峰期,秒殺期等)消息并發(fā)量非常大時,通過Sentinel起到“削峰填谷”的作用;
  2. 某個業(yè)務(wù)服務(wù)非常復(fù)雜,需要調(diào)用大量微服務(wù),其中某服務(wù)不可用時,不影響整體業(yè)務(wù)運行,如提交某個訂單,需要調(diào)用諸如驗證庫存,驗證優(yōu)惠金額,支付,驗證手機號等,其中驗證手機號服務(wù)不可用時,采用降級的方式讓其通過,不影響整個提交訂單的業(yè)務(wù);
  3. 上述訂單業(yè)務(wù)提交時,依賴的下游應(yīng)用控制線程數(shù),請求上下文超過閾值時,新的請求立即拒絕,即針對流控,可基于QPS或線程數(shù)在某些業(yè)務(wù)場景下,都會有用,如下就是一個qps瞬時拉大時,通過流量緩慢增加,避免系統(tǒng)被壓垮的情況:
image

隨著微服務(wù)的流行,服務(wù)和服務(wù)之間的穩(wěn)定性變得越來越重要。Sentinel 以流量為切入點,從流量控制、熔斷降級、系統(tǒng)負載保護等多個維度保護服務(wù)的穩(wěn)定性。

Sentinel 具有以下特征:

  • 豐富的應(yīng)用場景Sentinel 承接了阿里巴巴近 10 年的雙十一大促流量的核心場景,例如秒殺(即突發(fā)流量控制在系統(tǒng)容量可以承受的范圍)、消息削峰填谷、實時熔斷下游不可用應(yīng)用等。

  • 完備的實時監(jiān)控Sentinel 同時提供實時的監(jiān)控功能。您可以在控制臺中看到接入應(yīng)用的單臺機器秒級數(shù)據(jù),甚至 500 臺以下規(guī)模的集群的匯總運行情況。

  • 廣泛的開源生態(tài)Sentinel 提供開箱即用的與其它開源框架/庫的整合模塊,例如與 Spring CloudDubbogRPC 的整合。您只需要引入相應(yīng)的依賴并進行簡單的配置即可快速地接入 Sentinel

  • 完善的 SPI 擴展點Sentinel 提供簡單易用、完善的 SPI 擴展點。您可以通過實現(xiàn)擴展點,快速的定制邏輯。例如定制規(guī)則管理、適配數(shù)據(jù)源等。

Sentinel分為兩部分:

  1. 核心庫(Java 客戶端)不依賴任何框架/庫,能夠運行于所有 Java 運行時環(huán)境,同時對 Dubbo / Spring Cloud 等框架也有較好的支持。

  2. 控制臺(Dashboard)基于 Spring Boot 開發(fā),打包后可以直接運行,不需要額外的 Tomcat 等應(yīng)用容器,該模塊目前基于SpringBoot運行;

部署

在使用Sentinel之前,我們首先需部署Sentinel Dashborad,下載最新版的Sentinel Dashborad,通過以下命令運行:

java -Dserver.port=8088 -jar sentinel-dashboard-1.3.0.jar

通過server.port執(zhí)行程序運行端口號,通過http://localhost:8088打開控制臺,如下:

image

至此部署完成,非常簡單!

項目中使用Sentinel

Sentinel針對各個主流框架都提供了適配(包括Servlet,Dubbo,SpringBoot/SpringCloud,gRPC,RocketMQ等),本文以SpringBoot2舉例(通過筆者測試發(fā)現(xiàn),SpringBoot 1.x支持不好,自定義流控規(guī)則不可用),首先我們需要在SpringBoot2的配置文件中指定Sentinel連接的控制臺地址和項目名,即application.yml文件,如下:

project:
  name: 在控制臺顯示的項目名
spring:
  cloud:
    sentinel:
      transport:
        dashboard: 192.168.1.154:8088

在項目中加入依賴:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    <version>0.2.0.RELEASE</version>
</dependency>

啟動SpringBoot2后,可以在簇點鏈路頁面看到項目的各個服務(wù)(首次訪問服務(wù)時會被出現(xiàn)在列表中,這些服務(wù)在Sentinel中被稱為資源),接著,你就可以針對這些資源進行流控,降級,熱點,授權(quán)等操作。

流量控制與規(guī)則擴展

在控制臺可通過流控規(guī)則菜單定義某資源的流控規(guī)則,不過這個定義只在內(nèi)存中,但控制臺重啟后,隨之消失,所以我們一般在項目中通過配置文件來定義流控規(guī)則,編寫一個流控數(shù)據(jù)源,如下:

package com.sumscope.study.springboot2.service;

import java.net.URLDecoder;
import java.util.List;

import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.datasource.ReadableDataSource;
import com.alibaba.csp.sentinel.init.InitFunc;
import com.alibaba.csp.sentinel.datasource.FileRefreshableDataSource;
import com.alibaba.csp.sentinel.property.PropertyListener;
import com.alibaba.csp.sentinel.property.SentinelProperty;
import com.alibaba.csp.sentinel.slots.block.Rule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.csp.sentinel.slots.system.SystemRule;
import com.alibaba.csp.sentinel.slots.system.SystemRuleManager;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
public class FileDataSourceInit implements InitFunc{
    private Converter<String, List<FlowRule>> flowRuleListParser = source -> JSON.parseObject(source,
        new TypeReference<List<FlowRule>>() {});
    private Converter<String, List<DegradeRule>> degradeRuleListParser = source -> JSON.parseObject(source,
        new TypeReference<List<DegradeRule>>() {});
    private Converter<String, List<SystemRule>> systemRuleListParser = source -> JSON.parseObject(source,
        new TypeReference<List<SystemRule>>() {});
    @Override
    public void init() throws Exception {
        ClassLoader classLoader = getClass().getClassLoader();
        String flowRulePath = URLDecoder.decode(classLoader.getResource("FlowRule.json").getFile(), "UTF-8");
        String degradeRulePath = URLDecoder.decode(classLoader.getResource("DegradeRule.json").getFile(), "UTF-8");
        String systemRulePath = URLDecoder.decode(classLoader.getResource("SystemRule.json").getFile(), "UTF-8");

        // Data source for FlowRule
        FileRefreshableDataSource<List<FlowRule>> flowRuleDataSource = new FileRefreshableDataSource<>(
            flowRulePath, flowRuleListParser);
        FlowRuleManager.register2Property(flowRuleDataSource.getProperty());

        // Data source for DegradeRule
        FileRefreshableDataSource<List<DegradeRule>> degradeRuleDataSource
            = new FileRefreshableDataSource<>(
            degradeRulePath, degradeRuleListParser);
        DegradeRuleManager.register2Property(degradeRuleDataSource.getProperty());

        // Data source for SystemRule
        FileRefreshableDataSource<List<SystemRule>> systemRuleDataSource
            = new FileRefreshableDataSource<>(
            systemRulePath, systemRuleListParser);
        SystemRuleManager.register2Property(systemRuleDataSource.getProperty());
    }
}

然后在項目的resources下新增目錄META-INF\services\com.alibaba.csp.sentinel.init.InitFunc,并填寫以上類的完成類名如com.sumscope.study.springboot2.service.FileDataSourceInit即可,這樣,在您的classpath目錄下通過DegradeRule.json,FlowRule.json,SystemRule.json分別來定義降級規(guī)則,流控規(guī)則和系統(tǒng)規(guī)則,比如我們定義一個流控規(guī)則,讓test資源QPS為1,即1秒鐘最多調(diào)用1次,如下:

[
  {
    "resource": "test",
    "controlBehavior": 0,
    "count": 1,
    "grade": 1,
    "limitApp": "default",
    "strategy": 0
  }
]

在Java代碼中,通過@SentinelResource("test")來定義服務(wù)對應(yīng)的資源名,如果不指數(shù),URI即為資源名。

熔斷降級

降級規(guī)則定義如下:

image

可基于RT(平均響應(yīng)時間)或異常比例兩種方式來定義,其中RT單位為毫秒。

指定RT時,當資源的平均響應(yīng)時間超過閾值(DegradeRule 中的 count,以 ms 為單位)之后,資源進入準降級狀態(tài)。接下來如果持續(xù)進入 5 個請求,它們的 RT 都持續(xù)超過這個閾值,那么在接下的時間窗口(DegradeRule 中的 timeWindow,以 s 為單位)之內(nèi),對這個方法的調(diào)用都會自動地返回。

指定異常時,當資源的每秒異常總數(shù)占通過總數(shù)的比值超過閾值(DegradeRule 中的 count)之后,資源進入降級狀態(tài),即在接下的時間窗口(DegradeRule 中的 timeWindow,以 s 為單位)之內(nèi),對這個方法的調(diào)用都會自動地返回。

熱點參數(shù)限流

也可對經(jīng)常訪問的數(shù)據(jù)進行限流,如某個商品或某個用戶等,如下圖:

image

Sentinel 利用 LRU 策略,結(jié)合底層的滑動窗口機制來實現(xiàn)熱點參數(shù)統(tǒng)計。LRU 策略可以統(tǒng)計單位時間內(nèi),最近最常訪問的熱點參數(shù),而滑動窗口機制可以幫助統(tǒng)計每個參數(shù)的 QPS,熱點參數(shù)限流目前只支持QPS模式。

黑白名單

可通過定義策略(黑名單或白名單)限定資源的調(diào)用方是否讓其通過,以下是代碼定義白名單規(guī)則:

AuthorityRule rule = new AuthorityRule();
rule.setResource("test");
rule.setStrategy(RuleConstant.AUTHORITY_WHITE);
rule.setLimitApp("appA,appB");
AuthorityRuleManager.loadRules(Collections.singletonList(rule));

實時監(jiān)控

在控制臺我們可以實時看到每個資源的qps情況如下圖:

image

注:其中p_qps是每秒通過的請求數(shù),b_qps是每秒拒絕的請求數(shù)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容