Sentinel-dashboard限流规则持久化改造
本文来实现基于nacos推模式的规则持久化。
一、推模式架
TIPS图片来自官方。引用自
https://github.com/alibaba/Sentinel/wiki/在生产环境中使用-Sentinel
1 源码依赖修改和简单配置修改
注释sentinel-datasource-nacos依赖的使用范围
<!-- for Nacos rule publisher sample -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<!--<scope>test</scope>-->
</dependency>
配置应用启动端口,登录名密码(默认都是sentinel
)
server.port=8080
csp.sentinel.dashboard.server=localhost:8080
sentinel.dashboard.auth.username=sentinel
sentinel.dashboard.auth.password=sentinel
server.servlet.session.timeout=7200
sentinel.dashboard.nacos.server-addr=localhost:8848
2 移动test/rule下的nacos文件夹到dashboard/rule下
3 修改NacosConfigUtil文件
public final class NacosConfigUtil {
public static final String GROUP_ID = "SENTINEL_GROUP";
public static final String FLOW_DATA_ID_POSTFIX = "flow-rules-";
public static final String DEGRADE_DATA_ID_POSTFIX = "degrade-rules-";
public static final String SYSTEM_DATA_ID_POSTFIX = "system-rules-";
public static final String PARAM_FLOW_DATA_ID_POSTFIX = "param-rules-";
public static final String AUTHORITY_DATA_ID_POSTFIX = "authority-rules-";
public static final String CONSOLE_PREFIX= "console-";
public static final String CLIENT_PREFIX = "client-";
public static final String CLUSTER_MAP_DATA_ID_POSTFIX = "-cluster-map";
/**
* cc for `cluster-client`
*/
public static final String CLIENT_CONFIG_DATA_ID_POSTFIX = "-cc-config";
/**
* cs for `cluster-server`
*/
public static final String SERVER_TRANSPORT_CONFIG_DATA_ID_POSTFIX = "-cs-transport-config";
public static final String SERVER_FLOW_CONFIG_DATA_ID_POSTFIX = "-cs-flow-config";
public static final String SERVER_NAMESPACE_SET_DATA_ID_POSTFIX = "-cs-namespace-set";
private NacosConfigUtil() {
}
/**
* 将规则序列化成JSON文本,存储到Nacos server中
*
* @param configService nacos config service
* @param app 应用名称
* @param postfix 规则后缀 eg.NacosConfigUtil.FLOW_DATA_ID_POSTFIX
* @param rules 规则对象
* @throws NacosException 异常
*/
public static <T> void setRuleStringToNacos(ConfigService configService, String app, String postfix, List<T> rules) throws NacosException {
AssertUtil.notEmpty(app, "app name cannot be empty");
if (rules == null) {
return;
}
List<Rule> ruleForApp = rules.stream()
.map(rule -> {
RuleEntity rule1 = (RuleEntity) rule;
System.out.println(rule1.getClass());
Rule rule2 = rule1.toRule();
System.out.println(rule2.getClass());
return rule2;
})
.collect(Collectors.toList());
// 存储,给微服务使用
String dataId = genDataId(app, postfix);
configService.publishConfig(
CLIENT_PREFIX + dataId,
NacosConfigUtil.GROUP_ID,
JSONUtils.toJSONString(ruleForApp)
);
// 存储,给控制台使用
configService.publishConfig(
CONSOLE_PREFIX + dataId,
NacosConfigUtil.GROUP_ID,
JSONUtils.toJSONString(rules)
);
}
/**
* 从Nacos server中查询响应规则,并将其反序列化成对应ruleEntity实体
*
* @param configService nacos config service
* @param appName 应用名称
* @param postfix 规则后缀 eg.NacosConfigUtil.FLOW_DATA_ID_POSTFIX
* @param clazz 类
* @param <T> 泛型
* @return 规则对象列表
* @throws NacosException 异常
*/
public static <T> List<T> getRuleEntitiesFromNacos(ConfigService configService, String appName, String postfix, Class<T> clazz) throws NacosException {
String rules = configService.getConfig(
genDataId(appName, CONSOLE_PREFIX + postfix),
NacosConfigUtil.GROUP_ID,
3000
);
System.out.println("===============" + rules);
if (StringUtil.isEmpty(rules)) {
return new ArrayList<>();
}
return JSONUtils.parseObject(clazz, rules);
}
private static String genDataId(String appName, String postfix) {
return postfix + appName;
}
}
4 修改FlowRuleNacosPublisher 和 FlowRuleNacosProvider 源码
@Component("flowRuleNacosPublisher")
public class FlowRuleNacosPublisher implements DynamicRulePublisher<List<FlowRuleEntity>> {
@Autowired
private ConfigService configService;
@Override
public void publish(String app, List<FlowRuleEntity> rules) throws Exception {
NacosConfigUtil.setRuleStringToNacos(
this.configService,
app,
NacosConfigUtil.FLOW_DATA_ID_POSTFIX,
rules
);
}
}
@Component("flowRuleNacosProvider")
public class FlowRuleNacosProvider implements DynamicRuleProvider<List<FlowRuleEntity>> {
@Autowired
private ConfigService configService;
@Override
public List<FlowRuleEntity> getRules(String appName) throws Exception {
return NacosConfigUtil.getRuleEntitiesFromNacos(
this.configService,
appName,
NacosConfigUtil.FLOW_DATA_ID_POSTFIX,
FlowRuleEntity.class
);
}
}
5 修改controller/v2/FlowControllerV2
注入FlowRuleNacosPublisher 和 FlowRuleNacosProvider
@Autowired
@Qualifier("flowRuleNacosProvider")
private DynamicRuleProvider<List<FlowRuleEntity>> ruleProvider;
@Autowired
@Qualifier("flowRuleNacosPublisher")
private DynamicRulePublisher<List<FlowRuleEntity>> rulePublisher;
6 修改webapp/resources/app/scripts/directives/sidebar/sidebar-search/sidebar.html
添加以下代码:
<li ui-sref-active="active">
<a ui-sref="dashboard.flow({app: entry.app})">
<i class="glyphicon glyphicon-filter"></i> 流控规则-Nacos</a>
</li>
至此限流规则持久化完成。
这里持久化到nacos配置中心的每种规则会有两条,分别对应客户端和dashboard.欢迎各位大神提出更好的方案