一個名叫Sentinel-Rules-SDK的組件,使得Sentinel的流控&熔斷規則的配置更加方便

原文鏈接:一個名叫Sentinel-Rules-SDK的組件,使得Sentinel的流控&熔斷規則的配置更加方便

1 Sentinel 是什麼?

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

2 Sentinel 具有以下特徵:

豐富的應用場景:Sentinel 承接了阿里巴巴近 10 年的雙十一大促流量的核心場景,例如秒殺(即突發流量控制在系統容量可以承受的範圍)、消息削峯填谷、集羣流量控制、實時熔斷下游不可用應用等。
完備的實時監控:Sentinel 同時提供實時的監控功能。您可以在控制檯中看到接入應用的單臺機器秒級數據,甚至 500 臺以下規模的集羣的彙總運行情況。
廣泛的開源生態:Sentinel 提供開箱即用的與其它開源框架/庫的整合模塊,例如與 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相應的依賴並進行簡單的配置即可快速地接入 Sentinel。
完善的 SPI 擴展點:Sentinel 提供簡單易用、完善的 SPI 擴展接口。您可以通過實現擴展接口來快速地定製邏輯。例如定製規則管理、適配動態數據源等。

好了,其他的就不多做介紹了,大家可以看官網:https://github.com/alibaba/Sentinel/wiki/介紹

3 如何接入 Sentinel

之前我寫過一篇文章講Dubbo如何引入Sentinel做熔斷限流,而其中爲資源配置限流規則和熔斷規則有兩種方式:

  • 硬代碼初始化:我們可以利用 static 靜態代碼塊來初始化,但是如果項目每次要爲資源修改規則,就要修改項目代碼,然後重新打包部署
  • 利用控制檯來配置:因爲硬代碼的不方便,所以一般我們會利用控制檯來爲資源配置流控和熔斷規則。這個只能在項目啓動後獲取到所有資源,然後一個一個配置,但是這時候如果大流量打過來,就很容易導致系統崩潰。

所以暫時最好的實踐就是:硬代碼+控制檯

在項目啓動時,可以利用硬代碼先將資源初始化好,接着控制檯可以隨時調整根據線上的運行情況調整規則。

4 Sentinel-Rules-SDK

但是,在我看來,我還是比較喜歡將初始化規則維護在配置文件中,由配置中心統一管理Sentinel的流控規則和熔斷規則。

因爲有了上面的實踐和思考,所以自己研發了一款簡單易用的組件,將資源的流控&熔斷規則放在配置文件中。

  • 在項目啓動時,SDK會讀取配置文件中的配置,然後進行 Sentinel 規則的初始化;
  • 如果團隊還用了 Sentinel 提供的控制檯,當帶 Sentinel 規則的接口被調用時,就會將所有的限流規則和熔斷規則上傳到 Sentinel 控制檯中;
  • 接下來,我們可以在控制檯上看實時監控反饋的情況,根據需要來調整流控規則和熔斷規則,控制檯調整後的規則會同步到項目的內存中。

4.1 使用介紹

引入依賴:

<dependency>
    <groupId>com.github.howinfun</groupId>
    <artifactId>sentinel-rules-sdk</artifactId>
    <version>1.0.0-SNAPSHOT</version>
</dependency>

自己在本地拉代碼,然後deploy,最後引入依賴

規則配置:

屬性基本和Sentinel 提供的 FlowRule 和 DegradeRule 一一對應上,滿足基本功能點。
詳情看下面例子:

# 開啓組件功能
sentinel.rules.enabled=true
# 流控&熔斷規則配置
sentinel.rules.flowRuleList[0].resource=sayHello
sentinel.rules.flowRuleList[0].grade=1
sentinel.rules.flowRuleList[0].count=1

sentinel.rules.degradeRuleList[0].resource=sayHello
sentinel.rules.degradeRuleList[0].grade=2
sentinel.rules.degradeRuleList[0].count=1
sentinel.rules.degradeRuleList[0].timeWindow=1
sentinel.rules.degradeRuleList[0].minRequestAmount=1
sentinel.rules.degradeRuleList[0].statIntervalMs=10000

sentinel.rules.flowRuleList[1].resource=sayHi
sentinel.rules.flowRuleList[1].grade=1
sentinel.rules.flowRuleList[1].count=1

sentinel.rules.degradeRuleList[1].resource=sayHi
sentinel.rules.degradeRuleList[1].grade=2
sentinel.rules.degradeRuleList[1].count=1
sentinel.rules.degradeRuleList[1].timeWindow=1
sentinel.rules.degradeRuleList[1].minRequestAmount=1
sentinel.rules.degradeRuleList[1].statIntervalMs=10000

使用介紹已經結束,就是這麼簡單,畢竟原理其實就是拿到配置的內容,然後進行初始化。下面看看功能是如何實現的。

4.2 實現介紹

核心類有兩個:SentinelRulesProperties 和 SentinelRulesGenerateConfig

看名稱我們就知道這兩個類的功能點了。第一個是屬性類,負責讀取配置文件中的規則。第二個是配置類,負責初始化流控規則和熔斷規則。

SentinelRulesProperties:

SentinelRulesProperties 非常簡單,只是利用 @ConfigurationProperties 註解來完成配置規則的注入。
當然了,我們要記得找個地方利用 @EnableConfigurationProperties 將這個屬性類加上,不然讀取不了配置文件中的規則內容。

/**
 * Sentinel規則配置
 * @author winfun
 * @date 2021/3/4 4:26 下午
 **/
@Data
@ConfigurationProperties(prefix = "sentinel.rules")
public class SentinelRulesProperties {

    private Boolean enabled;
    private List<SentinelFlowRule> flowRuleList;
    private List<SentinelDegradeRule> degradeRuleList;
}

SentinelRulesGenerateConfig:

SentinelRulesGenerateConfig 配置類也很簡單,主要是利用 Spring 提供的監聽器,監聽ContextRefreshedEvent事件,即Spring容器初始化完畢,接着利用 ApplicationContext 來獲取上面的屬性類,然後讀取流控規則和熔斷規則,最後進行初始化。

/**
 * Sentinel規則自動生成配置類
 * @author winfun
 * @date 2021/3/4 4:29 下午
 **/
@Configuration
@ConditionalOnProperty(prefix = "sentinel.rules", name = "enabled", havingValue = "true")
@EnableConfigurationProperties({SentinelRulesProperties.class})
public class SentinelRulesGenerateConfig implements ApplicationListener<ContextRefreshedEvent>, ApplicationContextAware {

    private ApplicationContext applicationContext;

    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        SentinelRulesProperties sentinelRulesProperties =
                this.applicationContext.getBean(SentinelRulesProperties.class);
        List<SentinelFlowRule> flowRuleList = sentinelRulesProperties.getFlowRuleList();
        List<SentinelDegradeRule> degradeRuleList = sentinelRulesProperties.getDegradeRuleList();

        final List<FlowRule> flowRules = new ArrayList<>();
        final List<DegradeRule> degradeRules = new ArrayList<>();
        // 處理流控規則
        flowRuleList.forEach(sentinelFlowRule -> {
            FlowRule flowRule = new FlowRule();
            BeanUtils.copyProperties(sentinelFlowRule,flowRule);
            flowRules.add(flowRule);
        });
        // 處理熔斷規則
        degradeRuleList.forEach(sentinelDegradeRule -> {
            DegradeRule degradeRule = new DegradeRule();
            BeanUtils.copyProperties(sentinelDegradeRule,degradeRule);
            degradeRules.add(degradeRule);
        });
        FlowRuleManager.loadRules(flowRules);
        DegradeRuleManager.loadRules(degradeRules);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

如果大家對這個組件還感興趣的話,可以到Github上看看:https://github.com/Howinfun/study-in-work-and-life/tree/master/sentinel-rules-sdk

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