目錄
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/%E4%BB%8B%E7%BB%8D
https://yq.aliyun.com/articles/623424