Spring Cloud Alibaba | Sentinel: 分布式系統的流量防衛兵初探
Springboot: 2.1.6.RELEASE
SpringCloud: Greenwich.SR1
如無特殊說明,本系列文章全采用以上版本
1. Sentinel 是什么?
Sentinel 是阿里中間件團隊研發的面向分布式服務架構的輕量級高可用流量控制組件,最近正式開源。Sentinel 主要以流量為切入點,從流量控制、熔斷降級、系統負載保護等多個維度來幫助用戶保護服務的穩定性。講到這里,可能很多人會有疑問:Sentinel 和之前常用的熔斷降級庫 Netflix Hystrix 有什么異同呢?如果不清楚什么是Hystrix的,可以看我簽名的文章跟我學SpringCloud | 第四篇:熔斷器Hystrix。
下面我們通過一張表格來了解一下Sentinel和Hystrix的區別:
Sentinel | Hystrix | |
---|---|---|
隔離策略 | 基於並發數 | 線程池隔離/信號量隔離 |
熔斷降級策略 | 基於響應時間或失敗比率 | 基於失敗比率 |
實時指標實現 | 滑動窗口 | 滑動窗口(基於 RxJava) |
規則配置 | 支持多種數據源 | 支持多種數據源 |
擴展性 | 多個擴展點 | 插件的形式 |
基於注解的支持 | 支持 | 支持 |
調用鏈路信息 | 支持同步調用 | 不支持 |
限流 | 基於 QPS / 並發數,支持基於調用關系的限流 | 不支持 |
流量整形 | 支持慢啟動、勻速器模式 | 不支持 |
系統負載保護 | 支持 | 不支持 |
實時監控 API | 各式各樣 | 較為簡單 |
控制台 | 開箱即用,可配置規則、查看秒級監控、機器發現等 | 不完善 |
常見框架的適配 | Servlet、Spring Cloud、Dubbo、gRPC 等 | Servlet、Spring Cloud Netflix |
簡單看下來,Sentinel明顯比Hystrix功能更為強大。
Sentinel 以流量為切入點,從流量控制、熔斷降級、系統負載保護等多個維度保護服務的穩定性,所以被稱為分布式系統的流量防衛兵。
2. Sentinel 的特征:
- 豐富的應用場景: Sentinel 承接了阿里巴巴近 10 年的雙十一大促流量的核心場景,例如秒殺(即突發流量控制在系統容量可以承受的范圍)、消息削峰填谷、集群流量控制、實時熔斷下游不可用應用等。
- 完備的實時監控: Sentinel 同時提供實時的監控功能。您可以在控制台中看到接入應用的單台機器秒級數據,甚至 500 台以下規模的集群的匯總運行情況。
- 廣泛的開源生態: Sentinel 提供開箱即用的與其它開源框架/庫的整合模塊,例如與 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相應的依賴並進行簡單的配置即可快速地接入 Sentinel。
- 完善的 SPI 擴展點: Sentinel 提供簡單易用、完善的 SPI 擴展接口。您可以通過實現擴展接口來快速地定制邏輯。例如定制規則管理、適配動態數據源等。
Sentinel 的主要特性:
3. Sentinel 的開源生態:
Sentinel 分為兩個部分:
- 核心庫(Java 客戶端)不依賴任何框架/庫,能夠運行於所有 Java 運行時環境,同時對 Dubbo / Spring Cloud 等框架也有較好的支持。
- 控制台(Dashboard)基於 Spring Boot 開發,打包后可以直接運行,不需要額外的 Tomcat 等應用容器。
4. 簡單使用
4.1 項目依賴pom.xml
<!-- https://mvnrepository.com/artifact/com.alibaba.csp/sentinel-core -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
<version>1.6.2</version>
</dependency>
4.2 定義資源
接下來,我們把需要控制流量的代碼用 Sentinel API SphU.entry("HelloWorld") 和 entry.exit() 包圍起來即可。在下面的例子中,我們將 System.out.println("hello wolrd"); 作為資源,用 API 包圍起來。參考代碼如下:
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();
}
}
}
}
完成以上兩步后,代碼端的改造就完成了。
4.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);
// Set limit QPS to 20.
rule.setCount(20);
rules.add(rule);
FlowRuleManager.loadRules(rules);
}
完成上面 3 步,Sentinel 就能夠正常工作了。
4.4 Demo運行
Demo 運行之后,我們可以在日志 ~/logs/csp/${appName}-metrics.log.xxx 里看到下面的輸出:
|--timestamp-|------date time----|-resource-|p |block|s |e|rt
1563351614000|2019-07-17 16:20:14|HelloWorld|20|560|20|0|2|0
1563351615000|2019-07-17 16:20:15|HelloWorld|20|1441|20|0|0|0
1563351616000|2019-07-17 16:20:16|HelloWorld|20|2724|20|0|0|0
1563351617000|2019-07-17 16:20:17|HelloWorld|20|2348|20|0|0|0
其中 p 代表通過的請求, block 代表被阻止的請求, s 代表成功執行完成的請求個數, e 代表用戶自定義的異常, rt 代表平均響應時長。
可以看到,這個程序每秒穩定輸出 "hello world" 20 次,和規則中預先設定的閾值是一樣的。
Sentinel的簡單使用就到這里結束了,更多的進階使用歡迎關注后續的博客,謝謝。
參考:
https://github.com/alibaba/Sentinel/wiki/介紹
https://yq.aliyun.com/articles/623424