微服務輪子專案(17) -Alibaba Sentinel限流熔斷(動態規則擴充套件)
技術標籤:# 微服務輪子專案
文章目錄
1. 前言
在上一篇部落格《微服務輪子專案(16) -Alibaba Sentinel限流熔斷(使用示例)》,主要講解了Alibaba的限流熔斷框架Sentinel的基本使用,本文繼續來講解。
2. 規則
Sentinel 的理念是開發者只需要關注資源的定義,當資源定義成功後可以動態增加各種流控降級規則。Sentinel 提供兩種方式修改規則:
- 通過 API 直接修改 (loadRules)
- 通過DataSource適配不同資料來源修改
通過 API 修改比較直觀,可以通過以下幾個 API 修改不同的規則:
FlowRuleManager.loadRules(List<FlowRule> rules); // 修改流控規則
DegradeRuleManager.loadRules(List<DegradeRule> rules); // 修改降級規則
SystemRuleManager. loadRules(List<SystemRule> rules); // 修改系統規則
AuthorityRuleManager.loadRules(List<AuthorityRule> rules); // 修改授權規則
3. DataSource 擴充套件
上述loadRules()
方法只接受記憶體態的規則物件,但更多時候規則儲存在檔案、資料庫或者配置中心當中。DataSource
介面給我們提供了對接任意配置源的能力。相比直接通過 API 修改規則,實現DataSource介面是更加可靠的做法。
我們推薦 通過控制檯設定規則後將規則推送到統一的規則中心,客戶端實現ReadableDataSource
DataSource擴充套件常見的實現方式有:
- 拉模式:客戶端主動向某個規則管理中心定期輪詢拉取規則,這個規則中心可以是
RDBMS
、檔案,甚至是VCS
等。這樣做的方式是簡單,缺點是無法及時獲取變更; - 推模式:規則中心統一推送,客戶端通過註冊監聽器的方式時刻監聽變化,比如使用
Nacos
、Zookeeper
等配置中心。這種方式有更好的實時性和一致性保證。
3.1 拉模式擴充套件
- 實現拉模式的資料來源最簡單的方式是繼承AutoRefreshDataSource抽象類,然後實現
readSource()
方法,在該方法裡從指定資料來源讀取字串格式的配置資料。比如基於檔案的資料來源。
3.2 推模式擴充套件
實現推模式的資料來源最簡單的方式是繼承AbstractDataSource抽象類,在其構造方法中新增監聽器,並實現readSource()
從指定資料來源讀取字串格式的配置資料。比如基於Nacos 的資料來源。
控制檯通常需要做一些改造來直接推送應用維度的規則到配置中心。功能示例可以參考AHAS Sentinel 控制檯的規則推送功能。改造指南可以參考在生產環境中使用 Sentinel 控制檯。
3.3 註冊資料來源
通常需要呼叫以下方法將資料來源註冊至指定的規則管理器中:
ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new NacosDataSource<>(remoteAddress, groupId, dataId, parser);
FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
若不希望手動註冊資料來源,可以藉助Sentinel
的InitFuncSPI
擴充套件介面。只需要實現自己的InitFunc
介面,在init
方法中編寫註冊資料來源的邏輯。比如:
package com.test.init;
public class DataSourceInitFunc implements InitFunc {
@Override
public void init() throws Exception {
final String remoteAddress = "localhost";
final String groupId = "Sentinel:Demo";
final String dataId = "com.alibaba.csp.sentinel.demo.flow.rule";
ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new NacosDataSource<>(remoteAddress, groupId, dataId,
source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {}));
FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
}
}
接著將對應的類名新增到位於資源目錄(通常是resource目錄)下的META-INF/services
目錄下的com.alibaba.csp.sentinel.init.InitFunc
檔案中,比如:
com.test.init.DataSourceInitFunc
這樣,當初次訪問任意資源的時候,Sentinel
就可以自動去註冊對應的資料來源了。
4. 示例
4.1 API 模式:使用客戶端規則 API 配置規則
Sentinel Dashboard通過客戶端自帶的規則 API來實時查詢和更改記憶體中的規則。
注意: 要使客戶端具備規則 API,需在客戶端引入以下依賴:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentienl-http-simple-transport</artifactId>
<version>x.y.z</version>
</dependency>
4.2 拉模式:使用檔案配置規則
這個示例展示 Sentinel 是如何從檔案獲取規則資訊的。FileRefreshableDataSource會週期性的讀取檔案以獲取規則,當檔案有更新時會及時發現,並將規則更新到記憶體中。使用時只需新增以下依賴:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-extension</artifactId>
<version>x.y.z</version>
</dependency>
4.3 推模式:使用 Nacos 配置規則
Nacos是阿里中介軟體團隊開源的服務發現和動態配置中心。Sentinel 針對 Nacos 作了適配,底層可以採用 Nacos 作為規則配置資料來源。使用時只需新增以下依賴:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<version>x.y.z</version>
</dependency>
然後建立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());
詳細示例可以參見sentinel-demo-nacos-datasource。
4.4 推模式:使用 ZooKeeper 配置規則
Sentinel 針對 ZooKeeper 作了相應適配,底層可以採用 ZooKeeper 作為規則配置資料來源。使用時只需新增以下依賴:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-zookeeper</artifactId>
<version>x.y.z</version>
</dependency>
然後建立ZookeeperDataSource
並將其註冊至對應的 RuleManager
上即可。比如:
// remoteAddress 代表 ZooKeeper 服務端的地址
// path 對應 ZK 中的資料路徑
ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new ZookeeperDataSource<>(remoteAddress, path, source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {}));
FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
詳細示例可以參見sentinel-demo-zookeeper-datasource。
4.5 推模式:使用 Apollo 配置規則
Sentinel 針對Apollo作了相應適配,底層可以採用 Apollo 作為規則配置資料來源。使用時只需新增以下依賴:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-apollo</artifactId>
<version>x.y.z</version>
</dependency>
然後建立 ApolloDataSource
並將其註冊至對應的 RuleManager
上即可。比如:
// namespaceName 對應 Apollo 的名稱空間名稱
// ruleKey 對應規則儲存的 key
// defaultRules 對應連線不上 Apollo 時的預設規則
ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new ApolloDataSource<>(namespaceName, ruleKey, defaultRules, source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {}));
FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
詳細示例可以參見sentinel-demo-apollo-datasource。