摘要:sentinel-dashboard配置推送到nacos流程,由于配置规则众多,且大同小异,拿流控规则举例:
1.新建一个配置类,负责获取nacos服务相关配置,
2.新建一个负责将流控规则推送到nacos的类,例如FlowRuleNacosPublisher.java
3.新建一个负责从nacos配置中心读取配置规则的类,例如FlowRuleNacosProvider.java
4.新建一个负责分发流控规则相关业务逻辑的控制层类,例如FlowControllerV2.java,并将 2,3步新建的业务类注入进去,执行相关逻辑
5.找到对应的前端页面,将调用的业务接口改为新建的 控制层接口
!!!!!!!!!!!理解以后就可以进行下面的操作了
1. 从git上下载 sentinel-dashboard源码版本8.4,地址:https://github.com/alibaba/Sentinel
可以下载整个项目,也可以单独下载dashboard模块,具体自己决定
2.打开sentinel-dashboard模块下的,pom文件,因为要将配置推送到nacos将以下jar包作用域注释掉
com.alibaba.csp
sentinel-datasource-nacos
3.一般做法是将test文件夹下 com/alibaba/csp/sentinel/dashboard/nacos 下的四个类复制到
src/main/java/com/alibaba/csp/sentinel/dashboard/rule下,我这里做了一下修改,保险起见。可以直接复制我的代码。文件如下
FlowRuleNacosProvider.java
/**
* 从Nacos配置中心动态获取流控规则
*/
@Service
public class FlowRuleNacosProvider implements DynamicRuleProvider> {
private static Logger logger = LoggerFactory.getLogger(FlowRuleNacosProvider.class);
@Autowired
private NacosProperties nacosProperties;
@Autowired
private ConfigService configService;
@Autowired
private Converter> converter;
/**
* 从Nacos配置中心拉取流控规则配置文件
* @param appName 配置文件名
* @return
* @throws Exception
*/
@Override
public List getRules(String appName) throws Exception {
String dataId = new StringBuffer(appName).append(NacosConfigUtils.DATA_ID_POSTFIX).toString();
String rules = configService.getConfig(dataId, nacosProperties.getGroupId(), 3000);
logger.info("Nacos Config:{}", rules);
if (StringUtil.isEmpty(rules)) {
return new ArrayList<>();
}
return converter.convert(rules);
}
}
FlowRuleNacosPublisher.java
/**
* 动态上传流控规则到Nacos配置中心
*/
@Service
public class FlowRuleNacosPublisher implements DynamicRulePublisher> {
@Autowired
private NacosProperties nacosProperties;
@Autowired
private ConfigService configService;
@Autowired
private Converter, String> converter;
/**
* 像nacos配置中心推送流控规则文件
*
* @param appName
* @param rules list of rules to push
* @throws Exception
*/
@Override
public void publish(String appName, List rules) throws Exception {
AssertUtil.notEmpty(appName, "appName cannot be empty");
if (rules == null) {
return;
}
String dataId = new StringBuffer(appName).append(NacosConfigUtils.DATA_ID_POSTFIX).toString();
configService.publishConfig(dataId, nacosProperties.getGroupId(), converter.convert(rules));
}
}
NacosConfig.java 自定义nacos配置
/**
* Nacos配置类
*/
@EnableConfigurationProperties(NacosProperties.class)
@Configuration
public class NacosConfig {
@Bean
public Converter, String> flowRuleEntityEncoder() {
return JSON::toJSONString;
}
@Bean
public Converter> flowRuleEntityDecoder() {
return s -> JSON.parseArray(s, FlowRuleEntity.class);
}
/**
* Nacos配置服务
*
* @param nacosProperties
* @return
* @throws NacosException
*/
@Bean
public ConfigService nacosConfigService(NacosProperties nacosProperties) throws NacosException {
Properties properties = new Properties();
properties.put(PropertyKeyConst.SERVER_ADDR, nacosProperties.getServerAddr());
properties.put(PropertyKeyConst.NAMESPACE, nacosProperties.getNamespace());
return ConfigFactory.createConfigService(properties);
}
}
NacosConfigUtils.java 流控规则,生成配置文件的相关配置
public class NacosConfigUtils {
// 配置文件的后缀
public static final String DATA_ID_POSTFIX = "-flow-rules";
// 默认groupId
public static final String GROUP_ID = "DEFAULT_GROUP";
public static final String FLOW_DATA_ID_POSTFIX = "-flow-rules";
public static final String PARAM_FLOW_DATA_ID_POSTFIX = "-param-rules";
public static final String CLUSTER_MAP_DATA_ID_POSTFIX = "-cluster-map";
public static final String CLIENT_CONFIG_DATA_ID_POSTFIX = "-cc-config";
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";
}
NacosProperties.java
@ConfigurationProperties(prefix = "sentinel.nacos")
public class NacosProperties {
// Nacos相关配置
private String serverAddr;
private String dataId;
private String groupId;
private String namespace;
public String getServerAddr() {
return serverAddr;
}
public void setServerAddr(String serverAddr) {
this.serverAddr = serverAddr;
}
public String getDataId() {
return dataId;
}
public void setDataId(String dataId) {
this.dataId = dataId;
}
public String getGroupId() {
return groupId;
}
public void setGroupId(String groupId) {
this.groupId = groupId;
}
public String getNamespace() {
return namespace;
}
public void setNamespace(String namespace) {
this.namespace = namespace;
}
}
4.修改总的流控方法代码
src/main/java/com/alibaba/csp/sentinel/dashboard/controller/v2/FlowControllerV2.java
将注入的 默认的类 修改成 刚才自定义的类 ,这样就实现了推送相关配置到nacos,以及从nacos拉取相关配置
修改前
修改后
方便大家复制:
@Qualifier("flowRuleNacosProvider") @Qualifier("flowRuleNacosPublisher")
5.后端修改到此为止,下面进行前端修改
resources/app/scripts/directives/sidebar/sidebar.html
将上面的注释掉,将下面的flowV1改成flow,感兴趣的可以点dashboard.flow进去看一下
发现他调用的正式咱们自己修改过的 FlowControllerV2.java
修改前的
修改后的
6.配置文件 application.properties,底下新增nacos相关配置
7.测试用的微服务这里不过多赘述,你们自己看着写,需要注意一点,微服务配置中的groupid要与上图sentinel-dashboard配置中的groupid保持一致
好了,nacos-dashboard打包运行,到此为止,nacos已经实现流控配置持久化到nacos,以及从nacos拉取相关配置
8.进阶配置
此时你启动nacos-dashboard,正要到流控规则页面进行尝试时,你会发现
有个回到单机页面的按钮,你好奇的点了一下,满怀期待的进行配置,但是却发现配置不能生效,这是因为单机页面的执行的方法还是默认的方法,需要进行如下修改:
resources/app/views/flow_v2.html
两种方法:1.进到这个页面,找到执行的方法修改为自定义的V2类下的方法
2.注释掉按钮
为了方便快捷,我们直接注释
为了方便我们以后的配置,更为牛逼的进阶之旅开启,快上车
一般我们习惯从簇点链路直接配置流控,而不是到流控规则页面进行配置,但是问题来了,从簇点链路进行配置的不生效,按F12看请求会发现,他还是请求的 /v1/flow 而不是 /v2/flow
解决问题:
resources/app/scripts/controllers/identity.js
对比这修改,至于为什么这么改不再赘述,有兴趣的可以对比一下两个路径执行的方法
修改前
修改后
修改到这,你会发现从簇点链路配置的流程规则可以推送到nacos了,但是新问题,出现了,保存完后会自动跳转到展示页面,但是展示页面是空的~~~~~~~~~~~~~~
原因:F12查看请求得知,查询方法还是执行的V1版本的默认方法,而不是我们自定义的V2里面的方法,继续在当前js文件进行修改
修改前
修改后
我在这里新增了一个sleep方法,因为我发现每次新增完规则之后,跳转到展示页面,新增的规则没显示,需要刷新一两下,这是由于控制台推送到nacos,然后再从nacos拉取需要一定时间,所以我让页面等个1s在进行跳转,就可以显示出来新配置的规则了,有利也有弊,不喜欢的可以去掉
终于实现了分别在两个页面进行流控配置
一步步配置下来,方便快捷的sentinel控制台就实现了