核心内容摘要
困困对困困:一场关于“醒来”的温柔革命
Sentinel Nacos 规则持久化代码解析本文介绍 Sentinel Dashboard 集成 Nacos 作为动态规则配置中心的实现代码。
NacosConfig.java/* * Copyright
Alibaba Group Holding Ltd. * * Licensed under the Apache License, Version
0 (the License); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-
0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */packagecom.alibaba.csp.sentinel.dashboard.rule.nacos;importjava.util.List;importcom.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;importcom.alibaba.csp.sentinel.datasource.Converter;importcom.alibaba.fastjson.JSON;importcom.alibaba.nacos.api.config.ConfigFactory;importcom.alibaba.nacos.api.config.ConfigService;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;/** * author Eric Zhao * since
1.
0 */ConfigurationpublicclassNacosConfig{BeanpublicConverterListFlowRuleEntity,StringflowRuleEntityEncoder(){returnJSON::toJSONString;}BeanpublicConverterString,ListFlowRuleEntityflowRuleEntityDecoder(){returns-JSON.parseArray(s,FlowRuleEntity.class);}BeanpublicConfigServicenacosConfigService()throwsException{returnConfigFactory.createConfigService(localhost);}}NacosConfigUtil.java/* * Copyright
Alibaba Group Holding Ltd. * * Licensed under the Apache License, Version
0 (the License); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-
0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */packagecom.alibaba.csp.sentinel.dashboard.rule.nacos;/** * author Eric Zhao * since
1.
0 */publicfinalclassNacosConfigUtil{publicstaticfinalStringGROUP_IDSENTINEL_GROUP;publicstaticfinalStringFLOW_DATA_ID_POSTFIX-flow-rules;publicstaticfinalStringPARAM_FLOW_DATA_ID_POSTFIX-param-rules;publicstaticfinalStringCLUSTER_MAP_DATA_ID_POSTFIX-cluster-map;/** * cc for cluster-client */publicstaticfinalStringCLIENT_CONFIG_DATA_ID_POSTFIX-cc-config;/** * cs for cluster-server */publicstaticfinalStringSERVER_TRANSPORT_CONFIG_DATA_ID_POSTFIX-cs-transport-config;publicstaticfinalStringSERVER_FLOW_CONFIG_DATA_ID_POSTFIX-cs-flow-config;publicstaticfinalStringSERVER_NAMESPACE_SET_DATA_ID_POSTFIX-cs-namespace-set;privateNacosConfigUtil(){}}FlowRuleNacosPublisher.java/* * Copyright
Alibaba Group Holding Ltd. * * Licensed under the Apache License, Version
0 (the License); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-
0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */packagecom.alibaba.csp.sentinel.dashboard.rule.nacos;importjava.util.List;importcom.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;importcom.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher;importcom.alibaba.csp.sentinel.datasource.Converter;importcom.alibaba.csp.sentinel.util.AssertUtil;importcom.alibaba.nacos.api.config.ConfigService;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Component;/** * author Eric Zhao * since
1.
0 */Component(flowRuleNacosPublisher)publicclassFlowRuleNacosPublisherimplementsDynamicRulePublisherListFlowRuleEntity{AutowiredprivateConfigServiceconfigService;AutowiredprivateConverterListFlowRuleEntity,Stringconverter;Overridepublicvoidpublish(Stringapp,ListFlowRuleEntityrules)throwsException{AssertUtil.notEmpty(app,app name cannot be empty);if(rulesnull){return;}configService.publishConfig(appNacosConfigUtil.FLOW_DATA_ID_POSTFIX,NacosConfigUtil.GROUP_ID,converter.convert(rules));}}FlowRuleNacosProvider.java/* * Copyright
Alibaba Group Holding Ltd. * * Licensed under the Apache License, Version
0 (the License); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-
0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */packagecom.alibaba.csp.sentinel.dashboard.rule.nacos;importjava.util.ArrayList;importjava.util.List;importcom.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;importcom.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider;importcom.alibaba.csp.sentinel.datasource.Converter;importcom.alibaba.csp.sentinel.util.StringUtil;importcom.alibaba.nacos.api.config.ConfigService;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Component;/** * author Eric Zhao * since
1.
0 */Component(flowRuleNacosProvider)publicclassFlowRuleNacosProviderimplementsDynamicRuleProviderListFlowRuleEntity{AutowiredprivateConfigServiceconfigService;AutowiredprivateConverterString,ListFlowRuleEntityconverter;OverridepublicListFlowRuleEntitygetRules(StringappName)throwsException{StringrulesconfigService.getConfig(appNameNacosConfigUtil.FLOW_DATA_ID_POSTFIX,NacosConfigUtil.GROUP_ID,
;if(StringUtil.isEmpty(rules)){returnnewArrayList();}returnconverter.convert(rules);}}
NacosConfigUtil.java- 配置常量类这是一个工具类定义了 Nacos 中存储 Sentinel 规则的命名规范。
核心常量GROUP_IDSENTINEL_GROUP// Nacos 配置分组Data ID 后缀规范后缀用途示例-flow-rules流控规则myapp-flow-rules-param-rules热点参数规则myapp-param-rules-cluster-map集群映射配置myapp-cluster-map-cc-config集群客户端配置myapp-cc-config-cs-transport-config集群服务端传输配置myapp-cs-transport-config-cs-flow-config集群服务端流控配置myapp-cs-flow-config-cs-namespace-set集群服务端命名空间集myapp-cs-namespace-set作用统一管理 Nacos 配置的命名规则避免硬编码。
NacosConfig.java- Spring 配置类这是 Spring Boot 配置类用于创建 Nacos 相关的 Bean。
三个关键 Bean①flowRuleEntityEncoder- 规则编码器returnJSON::toJSONString;将ListFlowRuleEntity转换为 JSON 字符串用于发布规则到 Nacos 时序列化②flowRuleEntityDecoder- 规则解码器returns-JSON.parseArray(s,FlowRuleEntity.class);将 JSON 字符串解析为ListFlowRuleEntity用于从 Nacos 读取规则时反序列化③nacosConfigService- Nacos 客户端ConfigFactory.createConfigService(localhost);创建 Nacos ConfigService 实例注意这里硬编码了localhost生产环境需要改为实际的 Nacos 地址
FlowRuleNacosPublisher.java- 规则发布器实现DynamicRulePublisher接口负责将流控规则推送到 Nacos。
核心方法publicvoidpublish(Stringapp,ListFlowRuleEntityrules)throwsException{AssertUtil.notEmpty(app,app name cannot be empty);if(rulesnull){return;}configService.publishConfig(appNacosConfigUtil.FLOW_DATA_ID_POSTFIX,// Data ID: myapp-flow-rulesNacosConfigUtil.GROUP_ID,// Group: SENTINEL_GROUPconverter.convert(rules)// 转换为 JSON);}执行流程校验app 名称不为空构造 Data ID应用名 -flow-rules序列化规则通过converter将规则列表转为 JSON发布配置调用 Nacos API 发布到指定分组使用场景Dashboard 页面修改流控规则时规则保存到 Nacos 持久化
FlowRuleNacosProvider.java- 规则提供器实现DynamicRuleProvider接口负责从 Nacos 拉取流控规则。
核心方法publicListFlowRuleEntitygetRules(StringappName)throwsException{StringrulesconfigService.getConfig(appNameNacosConfigUtil.FLOW_DATA_ID_POSTFIX,// Data IDNacosConfigUtil.GROUP_ID,// Group3000// 超时 3 秒);if(StringUtil.isEmpty(rules)){returnnewArrayList();// 无配置返回空列表}returnconverter.convert(rules);// 反序列化}执行流程从 Nacos 获取配置根据 Data ID 和 Group 查询检查空值如果配置为空返回空列表反序列化将 JSON 字符串解析为规则对象列表使用场景Dashboard 启动时加载规则页面刷新时重新拉取规则架构设计亮点
解耦设计Publisher (发布) ←→ Nacos ←→ Provider (拉取)读写分离职责清晰通过接口定义易于扩展到其他配置中心Apollo、Consul 等
转换器模式ConverterListFlowRuleEntity,String// 编码ConverterString,ListFlowRuleEntity// 解码统一序列化/反序列化逻辑可替换 JSON 实现如换成 Jackson
配置规范化通过NacosConfigUtil统一命名规则避免不同模块使用不同的 Data ID 规范实际应用示例在 Nacos 中的配置结构Data ID: myapp-flow-rules Group: SENTINEL_GROUP Content: [ { resource: /api/test, limitApp: default, grade: 1, count: 10, strategy: 0, controlBehavior: 0 } ]Dashboard 使用流程用户在 Dashboard 修改规则调用FlowRuleNacosPublisher.publish()推送到 NacosNacos 通知客户端应用通过监听器客户端应用更新本地规则缓存Dashboard 通过FlowRuleNacosProvider.getRules()刷新显示
注意事项⚠️ 需要修改的地方Nacos 地址硬编码// 生产环境需要改为ConfigFactory.createConfigService(nacos-server:
;缺少命名空间配置// 建议添加 namespace 隔离不同环境PropertiespropertiesnewProperties();properties.put(serverAddr,localhost:
;properties.put(namespace,dev);ConfigFactory.createConfigService(properties);错误处理当前代码未处理 Nacos 连接失败的情况建议添加重试机制和降级策略这套代码提供了 Sentinel 与 Nacos 集成的标准实现模板是实现规则持久化的关键组件。
通过这种设计Dashboard 的规则修改可以持久化到 Nacos并自动同步到所有客户端应用。