在之前的練習(xí)中,只要應(yīng)用重啟,就需要重新配置,這樣在我們實際的項目是非常不實用的,那么有沒有辦法把我們配置的規(guī)則保存下來呢?答案是YES,那么接下來,給大家來介紹如何將Sentinel規(guī)則持久化。
十多年的從化網(wǎng)站建設(shè)經(jīng)驗,針對設(shè)計、前端、開發(fā)、售后、文案、推廣等六對一服務(wù),響應(yīng)快,48小時及時工作處理。成都全網(wǎng)營銷的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動調(diào)整從化建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計,從而大程度地提升瀏覽體驗。創(chuàng)新互聯(lián)公司從事“從化網(wǎng)站設(shè)計”,“從化網(wǎng)站推廣”以來,每個客戶項目都認(rèn)真落實執(zhí)行。
Document: 傳送門
原理:
擴(kuò)展寫數(shù)據(jù)源(WritableDataSource
), 客戶端主動向某個規(guī)則管理中心定期輪詢拉取規(guī)則,這個規(guī)則中心可以是 RDBMS、文件 等
pull 模式的數(shù)據(jù)源(如本地文件、RDBMS 等)一般是可寫入的。使用時需要在客戶端注冊數(shù)據(jù)源:將對應(yīng)的讀數(shù)據(jù)源注冊至對應(yīng)的 RuleManager,將寫數(shù)據(jù)源注冊至 transport 的WritableDataSourceRegistry
中。
過程如下:
Step 1: 添加配置
com.alibaba.csp
sentinel-datasource-extension
Step 2: 編寫持久化代碼,實現(xiàn)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存儲文件數(shù)據(jù)源加載類
*
* @author Isaac.Zhang | 若初
* @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);
// 流控規(guī)則
ReadableDataSource> flowRuleRDS = new FileRefreshableDataSource<>(
flowRulePath,
flowRuleListParser
);
// 將可讀數(shù)據(jù)源注冊至FlowRuleManager
// 這樣當(dāng)規(guī)則文件發(fā)生變化時,就會更新規(guī)則到內(nèi)存
FlowRuleManager.register2Property(flowRuleRDS.getProperty());
WritableDataSource> flowRuleWDS = new FileWritableDataSource<>(
flowRulePath,
this::encodeJson
);
// 將可寫數(shù)據(jù)源注冊至transport模塊的WritableDataSourceRegistry中
// 這樣收到控制臺推送的規(guī)則時,Sentinel會先更新到內(nèi)存,然后將規(guī)則寫入到文件中
WritableDataSourceRegistry.registerFlowDataSource(flowRuleWDS);
// 降級規(guī)則
ReadableDataSource> degradeRuleRDS = new FileRefreshableDataSource<>(
degradeRulePath,
degradeRuleListParser
);
DegradeRuleManager.register2Property(degradeRuleRDS.getProperty());
WritableDataSource> degradeRuleWDS = new FileWritableDataSource<>(
degradeRulePath,
this::encodeJson
);
WritableDataSourceRegistry.registerDegradeDataSource(degradeRuleWDS);
// 系統(tǒng)規(guī)則
ReadableDataSource> systemRuleRDS = new FileRefreshableDataSource<>(
systemRulePath,
systemRuleListParser
);
SystemRuleManager.register2Property(systemRuleRDS.getProperty());
WritableDataSource> systemRuleWDS = new FileWritableDataSource<>(
systemRulePath,
this::encodeJson
);
WritableDataSourceRegistry.registerSystemDataSource(systemRuleWDS);
// 授權(quán)規(guī)則
ReadableDataSource> authorityRuleRDS = new FileRefreshableDataSource<>(
flowRulePath,
authorityRuleListParser
);
AuthorityRuleManager.register2Property(authorityRuleRDS.getProperty());
WritableDataSource> authorityRuleWDS = new FileWritableDataSource<>(
authorityRulePath,
this::encodeJson
);
WritableDataSourceRegistry.registerAuthorityDataSource(authorityRuleWDS);
// 熱點參數(shù)規(guī)則
ReadableDataSource> hotParamFlowRuleRDS = new FileRefreshableDataSource<>(
hotParamFlowRulePath,
hotParamFlowRuleListParser
);
ParamFlowRuleManager.register2Property(hotParamFlowRuleRDS.getProperty());
WritableDataSource> paramFlowRuleWDS = new FileWritableDataSource<>(
hotParamFlowRulePath,
this::encodeJson
);
ModifyParamFlowRulesCommandHandler.setWritableDataSource(paramFlowRuleWDS);
}
/**
* 流控規(guī)則對象轉(zhuǎn)換
*/
private Converter> flowRuleListParser = source -> JSON.parseObject(
source,
new TypeReference>() {
}
);
/**
* 降級規(guī)則對象轉(zhuǎn)換
*/
private Converter> degradeRuleListParser = source -> JSON.parseObject(
source,
new TypeReference>() {
}
);
/**
* 系統(tǒng)規(guī)則對象轉(zhuǎn)換
*/
private Converter> systemRuleListParser = source -> JSON.parseObject(
source,
new TypeReference>() {
}
);
/**
* 授權(quán)規(guī)則對象轉(zhuǎn)換
*/
private Converter> authorityRuleListParser = source -> JSON.parseObject(
source,
new TypeReference>() {
}
);
/**
* 熱點規(guī)則對象轉(zhuǎn)換
*/
private Converter> hotParamFlowRuleListParser = source -> JSON.parseObject(
source,
new TypeReference>() {
}
);
/**
* 創(chuàng)建目錄
*
* @param filePath
*/
private void mkdirIfNotExits(String filePath) {
File file = new File(filePath);
if (!file.exists()) {
file.mkdirs();
}
}
/**
* 創(chuàng)建文件
*
* @param filePath
* @throws IOException
*/
private void createFileIfNotExits(String filePath) throws IOException {
File file = new File(filePath);
if (!file.exists()) {
file.createNewFile();
}
}
private String encodeJson(T t) {
return JSON.toJSONString(t);
}
}
Step 3: 啟用上述代碼
resource 目錄下創(chuàng)建 resources/META-INF/services
目錄并創(chuàng)建文件com.alibaba.csp.sentinel.init.InitFunc
,內(nèi)容為:
com.sxzhongf.sharedcenter.configuration.sentinel.datasource.FileDataSourceInit
FileRefreshableDataSource
定時更新,會有延遲)FileRefreshableDataSource
定時更新)推薦通過控制臺設(shè)置規(guī)則后將規(guī)則推送到統(tǒng)一的規(guī)則中心,客戶端實現(xiàn)
ReadableDataSource
接口端監(jiān)聽規(guī)則中心實時獲取變更,流程如下:
實現(xiàn)原理
shared_center service 加工
com.alibaba.csp
sentinel-datasource-nacos
spring:
cloud:
sentinel:
datasource:
sxzhongf_flow:
nacos:
server-addr: localhost:8848
dataId: ${spring.application.name}-flow-rules
groupId: SENTINEL_GROUP
# 規(guī)則類型,取值見: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 規(guī)則改造主要通過2個接口:
com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider
& com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher
Download Sentinel Source Code
sentinel-dashboard
項目下的POM文件
com.alibaba.csp
sentinel-datasource-nacos
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> ruleProvider;
@Autowired
// @Qualifier("flowRuleDefaultPublisher")
@Qualifier("flowRuleNacosPublisher")
private DynamicRulePublisher> rulePublisher;
/Sentinel-1.6.2/sentinel-dashboard/src/main/webapp/resources/app/scripts/directives/sidebar/sidebar.html
文件,修改代碼:
---
改為
-
??NACOS 流控規(guī)則 V1
Dashboard中要修改的代碼已經(jīng)好了。
重新啟動 Sentinel-dashboard mvn clean package -DskipTests
測試效果
Sentinel 添加流控規(guī)則:
Nacos 查看同步的配置: