写在前面
在1.8版本之前就已经支持规则持久化了,并且支持几种模式,这里就不一一赘述了,网上博客一搜一大片。这里只重点讲述一下1.8版本持久化sentinel规则到nacos。
示例代码
https://gitee.com/Pitta-Brachyura/sentinel-nacos.git
注意事项
sentinel持久化需要下载sentinel-dashboard源码,在源码上进行修改。
规则持久化
Dashboard规则持久化
- 点击前往GitHub下载sentinel-dashboard源码
- 建议单独创建一个项目,并把sentinel-dashboard模块copy到新建项目中
[可跳过本步骤]
- 添加依赖sentinel-dashboard自带依赖,但是
<scope>
域是test
,删除或注释即可
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
-
找到
test
工程下com.alibaba.csp.sentinel.rule.nacos
查看nacos持久化源码,因为这个持久化仅支持限流规则的持久化,所以并不打算直接copy过去直接用。
-
找到
main
工程下com.alibaba.csp.sentinel.rule
下创建nacos
包。[最终如下图]
-
创建
DynamicRuleEnums
用于规则工厂
import dpi.cloud.ms.sentinel.dashboard.datasource.entity.gateway.GatewayFlowRuleEntity;
import dpi.cloud.ms.sentinel.dashboard.datasource.entity.rule.*;
/**
* @author tangzedong.programmer@gamil.com
* @apiNote
* @since 2020/9/21 19:51
*/
public class DynamicEnums {
public enum Type {
Nacos("nacos");
private String name;
Type(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
public enum Rule {
FLOW(FlowRuleEntity.class, "flow"),
DEGRADE(DegradeRuleEntity.class, "degrade"),
SYSTEM(SystemRuleEntity.class, "system"),
AUTHORITY(AuthorityRuleEntity.class, "authority"),
PARAM_FLOW(ParamFlowRuleEntity.class, "param-flow"),
GATEWAY_FLOW(GatewayFlowRuleEntity.class, "gw-flow");
private Class entityClass;
private String key;
Rule(Class entityClass, String key) {
this.entityClass = entityClass;
this.key = key;
}
public <T> Class<T> getEntityClass() {
return entityClass;
}
public String getKey() {
return key;
}
}
}
- 创建
DynamicConstants
和DynamicConfigUtil
读取yml中的配置文件
public interface DynamicConstants {
String CONFIG = "spring.cloud.sentinel.datasource.{rule}.{type}.{property}";
String SERVER_ADDR = "server-addr";
String DATA_ID = "data-id";
String GROUP_ID = "group-id";
String RULE_TYPE = "rule-type";
String DATA_TYPE = "data-type";
}
public final class DynamicConfigUtil {
public static String getProperty(Environment environment, DynamicEnums.Type type, DynamicEnums.Rule rule, String property) {
return environment.getProperty(DynamicConstants.CONFIG
.replace("{type}", type.getName())
.replace("{rule}", rule.getKey())
.replace("{property}", property));
}
}
- 修改
DynamicRuleProvider.getRules
和DynamicRulePublisher.publish
规则[看到源代码就知道怎么改了,就不详细的把整个列的代码贴出来了]
/**
* 修改规则,增加规则枚举参数
*/
T getRules(String appName, DynamicEnums.Rule rule) throws Exception;
/**
* 修改规则,增加规则枚举参数
*/
void publish(String app, T rules, DynamicEnums.Rule rule) throws Exception;
- 创建
DynamicRuleNacosProvider
和DynamicRuleNacosPublisher
实现上述接口
@Component("DynamicRuleNacosProvider")
public class DynamicRuleNacosProvider<T> implements DynamicRuleProvider<List<T>> {
@Autowired
private ConfigService configService;
@Autowired
private Environment environment;
@Override
public List<T> getRules(String appName, DynamicEnums.Rule rule) throws Exception {
String rules = configService.getConfig(
DynamicConfigUtil.getProperty(environment, DynamicEnums.Type.Nacos, rule, DynamicConstants.DATA_ID),
DynamicConfigUtil.getProperty(environment, DynamicEnums.Type.Nacos, rule, DynamicConstants.GROUP_ID),
3000);
if (StringUtil.isEmpty(rules)) {
return new ArrayList<>();
}
return JSONArray.parseArray(rules, rule.getEntityClass());
}
}
@Component("DynamicRuleNacosPublisher")
public class DynamicRuleNacosPublisher<T> implements DynamicRulePublisher<List<T>> {
@Autowired
private ConfigService configService;
@Autowired
private Environment environment;
@Override
public void publish(String app, List<T> rules, DynamicEnums.Rule rule) throws Exception {
AssertUtil.notEmpty(app, "app name cannot be empty");
if (rules == null) {
return;
}
configService.publishConfig(
DynamicConfigUtil.getProperty(environment, DynamicEnums.Type.Nacos, rule, DynamicConstants.DATA_ID),
DynamicConfigUtil.getProperty(environment, DynamicEnums.Type.Nacos, rule, DynamicConstants.GROUP_ID),
JSON.toJSONString(rules));
}
}
- 代码逻辑就已经修改完毕,增加
yml
或者property
配置
spring:
cloud:
sentinel:
nacos-addr: ${ip}:${poer}
nacos-group-id: dpi-cloud-dev
data-type: json
datasource:
flow:
nacos:
server-addr: ${spring.cloud.sentinel.nacos-addr}
data-id: ${spring.application.name}-${spring.cloud.sentinel.datasource.flow.nacos.rule-type}-rules
group-id: ${spring.cloud.sentinel.nacos-group-id}
# 规则类型,取值见:org.springframework.cloud.alibaba.sentinel.datasource.RuleType
rule-type: flow
data-type: ${spring.cloud.sentinel.data-type}
degrade:
nacos:
server-addr: ${spring.cloud.sentinel.nacos-addr}
data-id: ${spring.application.name}-${spring.cloud.sentinel.datasource.degrade.nacos.rule-type}-rules
group-id: ${spring.cloud.sentinel.nacos-group-id}
rule-type: degrade
data-type: ${spring.cloud.sentinel.data-type}
system:
nacos:
server-addr: ${spring.cloud.sentinel.nacos-addr}
data-id: ${spring.application.name}-${spring.cloud.sentinel.datasource.system.nacos.rule-type}-rules
group-id: ${spring.cloud.sentinel.nacos-group-id}
rule-type: system
data-type: ${spring.cloud.sentinel.data-type}
authority:
nacos:
server-addr: ${spring.cloud.sentinel.nacos-addr}
data-id: ${spring.application.name}-${spring.cloud.sentinel.datasource.authority.nacos.rule-type}-rules
group-id: ${spring.cloud.sentinel.nacos-group-id}
rule-type: authority
data-type: ${spring.cloud.sentinel.data-type}
param-flow:
nacos:
server-addr: ${spring.cloud.sentinel.nacos-addr}
data-id: ${spring.application.name}-${spring.cloud.sentinel.datasource.param-flow.nacos.rule-type}-rules
group-id: ${spring.cloud.sentinel.nacos-group-id}
rule-type: param-flow
data-type: ${spring.cloud.sentinel.data-type}
gw-flow:
nacos:
server-addr: ${spring.cloud.sentinel.nacos-addr}
data-id: ${spring.application.name}-${spring.cloud.sentinel.datasource.gateway-flow.nacos.rule-type}-rules
group-id: ${spring.cloud.sentinel.nacos-group-id}
rule-type: gw-flow
data-type: ${spring.cloud.sentinel.data-type}
client端持久化
- 引入
maven
依赖,参考#dashboard持久化第3步[注:sentinel包本身需要引入,持久化则不额外说明]
- 增加
yml
配置,参考#dashboard持久化第11步