阿里開源Sentinel流控框架基本介紹與簡單使用
一、簡介
1. Sentinel 是什麼?
Sentinel是去年7月由阿里中間件團隊開源的,面向分佈式服務架構的輕量級高可用流量控制組件。
隨着微服務的流行,服務和服務之間的穩定性變得越來越重要。Sentinel 以流量爲切入點,從流量控制、熔斷降級、系統負載保護等多個維度保護服務的穩定性。
(引自官方文檔)
2. 主要優勢和特性
- 輕量級,核心庫無多餘依賴,性能損耗小。
- 方便接入,開源生態廣泛。
- 豐富的流量控制場景。
- 易用的控制檯,提供實時監控、機器發現、規則管理等能力。
- 完善的擴展性設計,提供多樣化的 SPI 接口,方便用戶根據需求給 Sentinel 添加自定義的邏輯。
3. 與Hystrix對比
之前大家熟知的容錯組件Hystrix,在去年宣佈停止開發,因此許多的開發人員在選型時將目光投向了Sentienl。這裏將它們做一下對比:
Sentinel | Hystrix | |
---|---|---|
隔離策略 | 信號量隔離 | 線程池隔離/信號量隔離 |
熔斷降級策略 | 基於響應時間或失敗比率 | 基於失敗比率 |
實時指標實現 | 滑動窗口 | 滑動窗口(基於 RxJava) |
規則配置 | 支持多種數據源 | 支持多種數據源 |
擴展性 | 多個擴展點 | 插件的形式 |
基於註解的支持 | 支持 | 支持 |
限流 | 基於 QPS,支持基於調用關係的限流 | 有限的支持 |
流量整形 | 支持慢啓動、勻速器模式 | 不支持 |
系統負載保護 | 支持 | 不支持 |
控制檯 | 開箱即用,可配置規則、查看秒級監控、機器發現等 | 不完善 |
常見框架的適配 | Servlet、Spring Cloud、Dubbo、gRPC 等 | Servlet、Spring Cloud Netflix |
二、核心概念
Resource
在Sentinel中,Resource-資源 是最重要的一個概念,可以是代碼塊、方法、接口等任何需要保護的東西。在編碼的時候,只需要考慮這個代碼是否需要保護,如果需要保護,就將之定義爲一個資源,然後定義規則就可以了,剩下的通通交給Sentinel來處理了。
Slot
Sentinel的工作流程就是圍繞着一個個插槽所組成的插槽鏈來展開的。每個插槽都有自己的功能,通過一定的編排順序,來達到最終的限流降級的目的。默認的各個插槽之間的順序是固定的,因爲有的插槽需要依賴其他的插槽計算出來的結果才能進行工作。
Context
Context 代表調用鏈路上下文,貫穿一次調用鏈路中的所有 Entry
。Context 維護着當前調用鏈的元數據:入口節點、本次調用鏈路節點、調用來源等信息,通過 ThreadLocal 傳遞。
Entry
Entry是Sentinel中用來表示請求是否通過限流的一個憑證。每次執行 SphU.entry()
或 SphO.entry()
都會返回一個 Entry
給調用者。資源調用結束時需要 entry.exit()
。
Entry
包含了資源名、curNode(當前統計節點)、originNode(來源統計節點)等信息。
Node
Sentinel中保存統計數據的對象:
StatisticNode
:最爲基礎的統計節點,包含秒級和分鐘級兩個滑動窗口結構。DefaultNode
:鏈路節點,用於統計調用鏈路上某個資源的數據,維持樹狀結構。ClusterNode
:簇節點,用於統計每個資源全局的數據(不區分調用鏈路),以及存放該資源的按來源區分的調用數據。EntranceNode
:入口節點,特殊的鏈路節點,對應某個 Context 入口的所有調用數據。
三、基本使用
1. 引入依賴
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
<version>1.7.1</version>
</dependency>
注意: 從 Sentinel 1.5.0 開始僅支持 JDK 1.7 或者以上版本。Sentinel 1.5.0 之前的版本最低支持 JDK 1.6。
2. 定義資源
Sentinel 在使用上提供了兩種形式,一種是異常捕獲形式,一種是布爾形式。也就是當限流被觸發時,是拋出異常來還是返回一個 false:
2.1 SphU-拋出異常的方式定義資源
Entry entry = null;
try {
entry = SphU.entry("myResource");
// 被保護的業務邏輯
} catch (BlockException e1) {
// 資源訪問阻止,被限流或被降級
// 進行相應的處理操作
} finally {
if (entry != null) {
entry.exit();
}
}
2.2 SphO-返回布爾值方式定義資源,當資源發生了限流之後就會返回false
if (SphO.entry("myResource")) {
try {
// 被保護的業務邏輯
} finally {
SphO.exit();
}
} else {
// 資源訪問阻止,被限流或被降級
// 進行相應的處理操作
}
2.3 使用註解
以上這兩種方式都是通過硬編碼的形式定義資源然後進行資源埋點的,對業務代碼的侵入太大,sentinel從0.1.1版本開始加入了註解的支持,可以通過@SentinelResource
註解來定義資源。通過註解除了可以定義資源外,還可配置 blockHandler
和 fallback
方法來進行限流之後的處理。
@SentinelResource(value = "myResource")
public void test() {
System.out.println("Hello World!");
}
3. 定義規則
使用 Sentinel 需要我們提供限流規則
private void initRules() {
// 配置規則
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule();
rule.setResource("myResource"); // 限流規則的作用對象
// 配置規則:QPS不得超出10
rule.setCount(10);
rule.setGrade(RuleConstant.FLOW_GRADE_QPS); // 設置限流閾值類型爲QPS模式
rule.setLimitApp("default"); // 針對的調用來源,default代表不區分來源
rules.add(rule);
// 加載規則
FlowRuleManager.loadRules(rules);
}
詳細使用示例參見:sentinel-demo-basic
四、動態配置規則
在上面的示例中,我們通過硬編碼來對資源進行規則配置,而在實際項目中,規則應該需要支持動態配置,Sentinel官方提供了多種DataSource(規則源)用於動態配置規則,比如Nacos、Apollo、Zookeeper等。
1. DataSource 擴展
DataSource
擴展常見的實現方式有:
- 拉模式:客戶端主動向某個規則管理中心定期輪詢拉取規則,這樣做的方式是簡單,缺點是無法及時獲取變更。(目前支持:文件、Consul)
- 推模式:規則中心統一推送,客戶端通過註冊監聽器的方式時刻監聽變化,這種方式有更好的實時性和一致性保證。(目前支持:ZooKeeper, Redis, Nacos, Apollo)
2. 使用 Nacos 作爲規則源
2.1 引入依賴
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<version>1.7.1</version>
</dependency>
2.2 註冊數據源
創建 NacosDataSource
並將其註冊至對應的 RuleManager 上即可。比如:
// remoteAddress 代表 Nacos 服務端的地址
// groupId 和 dataId 對應 Nacos 中相應配置
ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new NacosDataSource<>(remoteAddress, groupId, dataId,
source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {}));
FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
2.3 配置規則
在Nacos控制界面相應groupId和dataId下的配置內容中,使用json格式填寫配置內容:
[
{
"resource": "/myResource",
"limitApp": "default",
"grade": 1,
"count": 5,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
}
]
Nacos搭建及使用相關參見: Nacos整合SpringCloud實現配置管理和服務發現
詳細示例參見: sentinel-demo-nacos-datasource
五、Dashboard控制檯
Sentinel 提供一個輕量級的開源控制檯,它提供機器發現以及健康情況管理、監控(單機和集羣),規則管理和推送的功能。
1. 啓動控制檯
從release頁下載最新dashboard jar包:https://github.com/alibaba/Sentinel/releases
使用命令啓動:
# 指定控制檯端口爲8080
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
2. 客戶端接入控制檯
2.1 引入依賴
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
<version>1.7.1</version>
</dependency>
2.2 配置啓動參數
啓動時加入 JVM 參數 -Dcsp.sentinel.dashboard.server=consoleIp:port
指定控制檯地址和端口。
3. 查看應用情況
根據指定的控制檯端口,訪問http://localhost:8080/,即可打開管理頁面,查看機器列表和監控信息: