一個名叫Sentinel-Rules-SDK的元件,使得Sentinel的流控&熔斷規則的配置更加方便
阿新 • • 發佈:2021-03-15
# 原文連結:[一個名叫Sentinel-Rules-SDK的元件,使得Sentinel的流控&熔斷規則的配置更加方便](https://blog.csdn.net/Howinfun/article/details/114847396?spm=1001.2014.3001.5501)
## 1 Sentinel 是什麼?
隨著微服務的流行,服務和服務之間的穩定性變得越來越重要。Sentinel 以流量為切入點,從流量控制、熔斷降級、系統負載保護等多個維度保護服務的穩定性。
## 2 Sentinel 具有以下特徵:
豐富的應用場景:Sentinel 承接了阿里巴巴近 10 年的雙十一大促流量的核心場景,例如秒殺(即突發流量控制在系統容量可以承受的範圍)、訊息削峰填谷、叢集流量控制、實時熔斷下游不可用應用等。
完備的實時監控:Sentinel 同時提供實時的監控功能。您可以在控制檯中看到接入應用的單臺機器秒級資料,甚至 500 臺以下規模的叢集的彙總執行情況。
廣泛的開源生態:Sentinel 提供開箱即用的與其它開源框架/庫的整合模組,例如與 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相應的依賴並進行簡單的配置即可快速地接入 Sentinel。
完善的 SPI 擴充套件點:Sentinel 提供簡單易用、完善的 SPI 擴充套件介面。您可以通過實現擴充套件介面來快速地定製邏輯。例如定製規則管理、適配動態資料來源等。
好了,其他的就不多做介紹了,大家可以看官網:https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D
## 3 如何接入 Sentinel
之前我寫過一篇文章講[Dubbo如何引入Sentinel做熔斷限流](https://blog.csdn.net/Howinfun/article/details/113439208?spm=1001.2014.3001.5501),而其中為資源配置限流規則和熔斷規則有兩種方式:
- 硬程式碼初始化:我們可以利用 static 靜態程式碼塊來初始化,但是如果專案每次要為資源修改規則,就要修改專案程式碼,然後重新打包部署
- 利用控制檯來配置:因為硬程式碼的不方便,所以一般我們會利用控制檯來為資源配置流控和熔斷規則。這個只能在專案啟動後獲取到所有資源,然後一個一個配置,但是這時候如果大流量打過來,就很容易導致系統崩潰。
所以暫時最好的實踐就是:硬程式碼+控制檯
在專案啟動時,可以利用硬程式碼先將資源初始化好,接著控制檯可以隨時調整根據線上的執行情況調整規則。
## 4 Sentinel-Rules-SDK
但是,在我看來,我還是比較喜歡將初始化規則維護在配置檔案中,由配置中心統一管理Sentinel的流控規則和熔斷規則。
因為有了上面的實踐和思考,所以自己研發了一款簡單易用的元件,將資源的流控&熔斷規則放在配置檔案中。
- 在專案啟動時,SDK會讀取配置檔案中的配置,然後進行 Sentinel 規則的初始化;
- 如果團隊還用了 Sentinel 提供的控制檯,當帶 Sentinel 規則的介面被呼叫時,就會將所有的限流規則和熔斷規則上傳到 Sentinel 控制檯中;
- 接下來,我們可以在控制檯上看實時監控反饋的情況,根據需要來調整流控規則和熔斷規則,控制檯調整後的規則會同步到專案的記憶體中。
### 4.1 使用介紹
**引入依賴:**
```xml
com.github.howinfun
sentinel-rules-sdk
1.0.0-SNAPSHOT
```
> 自己在本地拉程式碼,然後deploy,最後引入依賴
**規則配置:**
屬性基本和Sentinel 提供的 FlowRule 和 DegradeRule 一一對應上,滿足基本功能點。
詳情看下面例子:
```properties
# 開啟元件功能
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 將這個屬性類加上,不然讀取不了配置檔案中的規則內容。
```java
/**
* Sentinel規則配置
* @author winfun
* @date 2021/3/4 4:26 下午
**/
@Data
@ConfigurationProperties(prefix = "sentinel.rules")
public class SentinelRulesProperties {
private Boolean enabled;
private List flowRuleList;
private List degradeRuleList;
}
```
**SentinelRulesGenerateConfig:**
SentinelRulesGenerateConfig 配置類也很簡單,主要是利用 Spring 提供的監聽器,監聽ContextRefreshedEvent事件,即Spring容器初始化完畢,接著利用 ApplicationContext 來獲取上面的屬性類,然後讀取流控規則和熔斷規則,最後進行初始化。
```java
/**
* 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, ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
SentinelRulesProperties sentinelRulesProperties =
this.applicationContext.getBean(SentinelRulesProperties.class);
List flowRuleList = sentinelRulesProperties.getFlowRuleList();
List degradeRuleList = sentinelRulesProperties.getDegradeRuleList();
final List flowRules = new ArrayList<>();
final List 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-ru