您好,登錄后才能下訂單哦!
在之前的練習中,只要應用重啟,就需要重新配置,這樣在我們實際的項目是非常不實用的,那么有沒有辦法把我們配置的規則保存下來呢?答案是YES,那么接下來,給大家來介紹如何將Sentinel規則持久化。
Document: 傳送門
原理:
擴展寫數據源(WritableDataSource
), 客戶端主動向某個規則管理中心定期輪詢拉取規則,這個規則中心可以是 RDBMS、文件 等
pull 模式的數據源(如本地文件、RDBMS 等)一般是可寫入的。使用時需要在客戶端注冊數據源:將對應的讀數據源注冊至對應的 RuleManager,將寫數據源注冊至 transport 的WritableDataSourceRegistry
中。
過程如下:
Step 1: 添加配置
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-extension</artifactId>
</dependency>
Step 2: 編寫持久化代碼,實現com.alibaba.csp.sentinel.init.InitFunc
import com.alibaba.csp.sentinel.command.handler.ModifyParamFlowRulesCommandHandler;
import com.alibaba.csp.sentinel.datasource.*;
import com.alibaba.csp.sentinel.init.InitFunc;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRuleManager;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRuleManager;
import com.alibaba.csp.sentinel.slots.system.SystemRule;
import com.alibaba.csp.sentinel.slots.system.SystemRuleManager;
import com.alibaba.csp.sentinel.transport.util.WritableDataSourceRegistry;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import java.io.File;
import java.io.IOException;
import java.util.List;
/**
* FileDataSourceInit for : 自定義Sentinel存儲文件數據源加載類
*
* @author <a href="mailto:magicianisaac@gmail.com">Isaac.Zhang | 若初</a>
* @since 2019/7/21
*/
public class FileDataSourceInit implements InitFunc {
@Override
public void init() throws Exception {
// TIPS: 如果你對這個路徑不喜歡,可修改為你喜歡的路徑
String ruleDir = System.getProperty("user.home") + "/sentinel/rules";
String flowRulePath = ruleDir + "/flow-rule.json";
String degradeRulePath = ruleDir + "/degrade-rule.json";
String systemRulePath = ruleDir + "/system-rule.json";
String authorityRulePath = ruleDir + "/authority-rule.json";
String hotParamFlowRulePath = ruleDir + "/param-flow-rule.json";
this.mkdirIfNotExits(ruleDir);
this.createFileIfNotExits(flowRulePath);
this.createFileIfNotExits(degradeRulePath);
this.createFileIfNotExits(systemRulePath);
this.createFileIfNotExits(authorityRulePath);
this.createFileIfNotExits(hotParamFlowRulePath);
// 流控規則
ReadableDataSource<String, List<FlowRule>> flowRuleRDS = new FileRefreshableDataSource<>(
flowRulePath,
flowRuleListParser
);
// 將可讀數據源注冊至FlowRuleManager
// 這樣當規則文件發生變化時,就會更新規則到內存
FlowRuleManager.register2Property(flowRuleRDS.getProperty());
WritableDataSource<List<FlowRule>> flowRuleWDS = new FileWritableDataSource<>(
flowRulePath,
this::encodeJson
);
// 將可寫數據源注冊至transport模塊的WritableDataSourceRegistry中
// 這樣收到控制臺推送的規則時,Sentinel會先更新到內存,然后將規則寫入到文件中
WritableDataSourceRegistry.registerFlowDataSource(flowRuleWDS);
// 降級規則
ReadableDataSource<String, List<DegradeRule>> degradeRuleRDS = new FileRefreshableDataSource<>(
degradeRulePath,
degradeRuleListParser
);
DegradeRuleManager.register2Property(degradeRuleRDS.getProperty());
WritableDataSource<List<DegradeRule>> degradeRuleWDS = new FileWritableDataSource<>(
degradeRulePath,
this::encodeJson
);
WritableDataSourceRegistry.registerDegradeDataSource(degradeRuleWDS);
// 系統規則
ReadableDataSource<String, List<SystemRule>> systemRuleRDS = new FileRefreshableDataSource<>(
systemRulePath,
systemRuleListParser
);
SystemRuleManager.register2Property(systemRuleRDS.getProperty());
WritableDataSource<List<SystemRule>> systemRuleWDS = new FileWritableDataSource<>(
systemRulePath,
this::encodeJson
);
WritableDataSourceRegistry.registerSystemDataSource(systemRuleWDS);
// 授權規則
ReadableDataSource<String, List<AuthorityRule>> authorityRuleRDS = new FileRefreshableDataSource<>(
flowRulePath,
authorityRuleListParser
);
AuthorityRuleManager.register2Property(authorityRuleRDS.getProperty());
WritableDataSource<List<AuthorityRule>> authorityRuleWDS = new FileWritableDataSource<>(
authorityRulePath,
this::encodeJson
);
WritableDataSourceRegistry.registerAuthorityDataSource(authorityRuleWDS);
// 熱點參數規則
ReadableDataSource<String, List<ParamFlowRule>> hotParamFlowRuleRDS = new FileRefreshableDataSource<>(
hotParamFlowRulePath,
hotParamFlowRuleListParser
);
ParamFlowRuleManager.register2Property(hotParamFlowRuleRDS.getProperty());
WritableDataSource<List<ParamFlowRule>> paramFlowRuleWDS = new FileWritableDataSource<>(
hotParamFlowRulePath,
this::encodeJson
);
ModifyParamFlowRulesCommandHandler.setWritableDataSource(paramFlowRuleWDS);
}
/**
* 流控規則對象轉換
*/
private Converter<String, List<FlowRule>> flowRuleListParser = source -> JSON.parseObject(
source,
new TypeReference<List<FlowRule>>() {
}
);
/**
* 降級規則對象轉換
*/
private Converter<String, List<DegradeRule>> degradeRuleListParser = source -> JSON.parseObject(
source,
new TypeReference<List<DegradeRule>>() {
}
);
/**
* 系統規則對象轉換
*/
private Converter<String, List<SystemRule>> systemRuleListParser = source -> JSON.parseObject(
source,
new TypeReference<List<SystemRule>>() {
}
);
/**
* 授權規則對象轉換
*/
private Converter<String, List<AuthorityRule>> authorityRuleListParser = source -> JSON.parseObject(
source,
new TypeReference<List<AuthorityRule>>() {
}
);
/**
* 熱點規則對象轉換
*/
private Converter<String, List<ParamFlowRule>> hotParamFlowRuleListParser = source -> JSON.parseObject(
source,
new TypeReference<List<ParamFlowRule>>() {
}
);
/**
* 創建目錄
*
* @param filePath
*/
private void mkdirIfNotExits(String filePath) {
File file = new File(filePath);
if (!file.exists()) {
file.mkdirs();
}
}
/**
* 創建文件
*
* @param filePath
* @throws IOException
*/
private void createFileIfNotExits(String filePath) throws IOException {
File file = new File(filePath);
if (!file.exists()) {
file.createNewFile();
}
}
private <T> String encodeJson(T t) {
return JSON.toJSONString(t);
}
}
Step 3: 啟用上述代碼
resource 目錄下創建 resources/META-INF/services
目錄并創建文件com.alibaba.csp.sentinel.init.InitFunc
,內容為:
com.sxzhongf.sharedcenter.configuration.sentinel.datasource.FileDataSourceInit
FileRefreshableDataSource
定時更新,會有延遲)FileRefreshableDataSource
定時更新)推薦通過控制臺設置規則后將規則推送到統一的規則中心,客戶端實現
ReadableDataSource
接口端監聽規則中心實時獲取變更,流程如下:
<img src="https://user-images.githubusercontent.com/9434884/45406233-645e8380-b698-11e8-8199-0c917403238f.png" width="500" />
實現原理
shared_center service 加工
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
spring:
cloud:
sentinel:
datasource:
sxzhongf_flow:
nacos:
server-addr: localhost:8848
dataId: ${spring.application.name}-flow-rules
groupId: SENTINEL_GROUP
# 規則類型,取值見:org.springframework.cloud.alibaba.sentinel.datasource.RuleType
rule_type: flow
sxzhongf_degrade:
nacos:
server-addr: localhost:8848
dataId: ${spring.application.name}-degrade-rules
groupId: SENTINEL_GROUP
rule-type: degrade
Sentinel dashboard 加工
Dashboard 規則改造主要通過2個接口:
com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider
& com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher
Download Sentinel Source Code
sentinel-dashboard
項目下的POM文件 <!-- for Nacos rule publisher sample -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<!--注釋掉原文件中的scope,讓其不僅在test的時候生效-->
<!--<scope>test</scope>-->
</dependency>
sentinel-dashboard
項目下test下的nacos包(src/test/java/com/alibaba/csp/sentinel/dashboard/rule/nacos
到 src/main/java/com/alibaba/csp/sentinel/dashboard/rule
下
com.alibaba.csp.sentinel.dashboard.controller.v2.FlowControllerV2
中
@Autowired
// @Qualifier("flowRuleDefaultProvider")
@Qualifier("flowRuleNacosProvider")
private DynamicRuleProvider<List<FlowRuleEntity>> ruleProvider;
@Autowired
// @Qualifier("flowRuleDefaultPublisher")
@Qualifier("flowRuleNacosPublisher")
private DynamicRulePublisher<List<FlowRuleEntity>> rulePublisher;
/Sentinel-1.6.2/sentinel-dashboard/src/main/webapp/resources/app/scripts/directives/sidebar/sidebar.html
文件,修改代碼:<!--<li ui-sref-active="active">-->
<!--<a ui-sref="dashboard.flow({app: entry.app})">-->
<!--<i class="glyphicon glyphicon-filter"></i>??流控規則 V1</a>-->
<!--</li>-->
---
改為
<li ui-sref-active="active">
<a ui-sref="dashboard.flow({app: entry.app})">
<i class="glyphicon glyphicon-filter"></i>??NACOS 流控規則 V1</a>
</li>
Dashboard中要修改的代碼已經好了。
重新啟動 Sentinel-dashboard mvn clean package -DskipTests
測試效果
Sentinel 添加流控規則:
Nacos 查看同步的配置:
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。