sentinel-dashboard改造持久化至nacos


由於使用到sentinel限流,需要對sentinel控制台進行改造,將流控規則持久化到nacos上。然后在網上尋找一些快速入口,發現幾乎是千篇一律,都是提供了一個flow的示例。
即在官方源碼中提供的test中的com.alibaba.csp.sentinel.dashboard的rule包下,但是如果使用這個規則會發生問題,sentinel計量服務獲取不到nacos上的熱點和授權規則的值,
經查驗發現從dashboard上推送規則存儲的時候,resource不在第一級目錄,即存儲規則的數據結構和客戶端的不對等。

由此可以分析,是不是Authority和param-flow在推送的publisher或者去獲取規則的provider不適配?針對Converter做一些操作。

我們先來看看flow,degrade,以及system的持久化到nacos上的做法,再來分析一下這個原理.

1.新建一個FlowRuleNacosProvider 來實現 DynamicRuleProvider用來讀取存在nacos上的流控規則文件

2.新建一個FlowRuleNacosPublisher 來實現 DynamicRulePublisher 用來發布流控規則至nacos上

3.寫一些轉換器將規則對象轉換成json字符串發布到nacos上,以及將從nacos上讀取的json字符串轉換成規則對象

4.最后將這些peovider和publish在各自的規則controller中替換掉 SentinelApiClient(操作內存的規則對象)

@Autowired
@Qualifier("flowRuleNacosProvider")
private DynamicRuleProvider<List<FlowRuleEntity>> ruleProvider;
@Autowired
@Qualifier("flowRuleNacosPublisher")
private DynamicRulePublisher<List<FlowRuleEntity>> rulePublisher;

List<FlowRuleEntity> rules = ruleProvider.getRules(app);

private void publishRules(/*@NonNull*/ String app) throws Exception {
    List<FlowRuleEntity> rules = repository.findAllByApp(app);
    rulePublisher.publish(app, rules);
}

看看param,Authority,以及gateway的持久化到nacos上的做法

1.新建一個FlowRuleNacosProvider 來實現 DynamicRuleProvider用來讀取存在nacos上的流控規則文件

2.編寫發布規則的轉換器

@Bean
public Converter<List<ParamFlowRuleEntity>, String> paramRuleEntityEncoder() {
    return rules -> JSON.toJSONString(
            rules.stream().map(ParamFlowRuleEntity::getRule).collect(Collectors.toList()));
}

param,Authority 和前面三個的不同之處只在於這兩處,網關也類似於這個。

分析以及解決方法思路

FlowRuleEntity implements RuleEntity
ParamFlowRuleEntity extends AbstractRuleEntity
從上面兩類的繼承結構中可以看出,兩個規則類的結構是不一樣的,來看看AbstractRuleEntity中做了什么

AbstractRuleEntity 中將規則封裝進了一個對象屬性rule中,導致兩種規則的結構不一致,自然發布規則和讀取規則的轉換也不一致。
那為什么要進行這樣的修改呢,其實模仿內存中的做法就行了(原生SentinelApiClient是利用Socket進行推到客戶端的),只是規則存放目標地址變更而已。

動態實現數據源原理

正常持久化的兩種思路:pull 和 push
①采用pull模式,擴展寫數據源(WritableDataSource),即sentinel控制台改變規則后就推到本地文件,客戶端主動向這個文件定期輪詢拉取規則;
②push模式,擴展讀數據源(ReadableDataSource),規則中心統一推送,客戶端通過注冊監聽器的方式時刻監聽變化,比如使用nacos,zk等配置中心

詳見官網注冊數據源的兩種方式https://github.com/alibaba/Sentinel/wiki/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%99%E6%89%A9%E5%B1%95:

①調用以下方法將數據源注冊至指定的規則管理器中:
ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new NacosDataSource<>(remoteAddress, groupId, dataId, parser);
FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
②借助 Sentinel 的 InitFunc SPI 擴展接口

采用push模式的話,以nacos為例,需要改寫sentinel-dashboard源碼,使得在dashboard上更改規則時,能夠將規則推送到nacos上

DynamicRuleProvider<T>: 拉取規則
DynamicRulePublisher<T>: 推送規則


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM