一、首先下载sentinel的源码
https://github.com/alibaba/Sentinel
二、修改sentinel的jar包 注释scope ,不然无法在主程序中使用
<dependency>
<groupId>com.alibaba.cspgroupId>
<artifactId>sentinel-datasource-nacosartifactId>
dependency>
三、修改sentinel的sidebar.html页面
将dashboard.flowV1修改成dashboard.flow
flowV1表示指向FlowControllerV1控制器,这个控制器目前是没有动态规则的相关代码的
修改成dashboard.flow后会指向FlowControllerV2控制器
四、在com.alibaba.csp.sentinel.dashboard.rule下增加一个nacos包
五、添加NacosConfig的配置类
@Configuration
public class NacosConfig {
@Bean
public Converter<List<FlowRuleEntity>, String> flowRuleEntityEncoder() {
return JSON::toJSONString;
}
@Bean
public Converter<String, List<FlowRuleEntity>> flowRuleEntityDecoder() {
return s -> JSON.parseArray(s, FlowRuleEntity.class);
}
@Bean
public ConfigService nacosConfigService() throws Exception {
Properties properties = new Properties();
//定义IP和端口,如果不指定端口则默认8848
properties.put(PropertyKeyConst.SERVER_ADDR, "127.0.0.1");
return ConfigFactory.createConfigService(properties);
}
}
六、添加FlowRuleNacosPublisher和 FlowRuleNacosProvider两个类
@Component("flowRuleNacosProvider")
public class FlowRuleNacosProvider implements DynamicRuleProvider<List<FlowRuleEntity>> {
@Autowired
private ConfigService configService;
@Autowired
private Converter<String, List<FlowRuleEntity>> converter;
public static final String FLOW_DATA_ID_POSTFIX = "-sentinel";
public static final String GROUP_ID = "DEFAULT_GROUP";
@Override
public List<FlowRuleEntity> getRules(String appName) throws Exception {
String rules = configService.getConfig(appName + FLOW_DATA_ID_POSTFIX, GROUP_ID, 3000);
if (StringUtil.isEmpty(rules)) {
return new ArrayList<>();
}
return converter.convert(rules);
}
}
@Component("flowRuleNacosPublisher")
public class FlowRuleNacosPublisher implements DynamicRulePublisher<List<FlowRuleEntity>> {
@Autowired
private ConfigService configService;
@Autowired
private Converter<List<FlowRuleEntity>, String> converter;
public static final String FLOW_DATA_ID_POSTFIX = "-sentinel";
public static final String GROUP_ID = "DEFAULT_GROUP";
@Override
public void publish(String app, List<FlowRuleEntity> rules) throws Exception {
AssertUtil.notEmpty(app, "app name cannot be empty");
if (rules == null) {
return;
}
configService.publishConfig(app + FLOW_DATA_ID_POSTFIX, GROUP_ID, converter.convert(rules));
}
}
七、修改FlowControllerV2
声明nacos的动态实现类
推送配置
publishConfig会从ServerListManager获取nacos的调用地址和端口通过httpPost发送到nacos的服务地址。
以上代码都和src/test/java中一样。
**
ConfigurationClassPostProcessor.enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory)
Spring的ConfigurationClassPostProcessor这个类会把有@Configuration的类都放在beanFactory的这个变量中,比如前面的NacosConfig类,在启动的时候就会被Spring加载
接下来的启动过程中Spring会调用nacosConfigService这个方法 ,在方法里面声明目标服务的相关配置
这里可以根据需要在去指定其他不同的配置。
接着ConfigFactory创建ConfigService
调用NacosConfigService的构造方法
agent = new MetricsHttpAgent(new ServerHttpAgent(properties));
创建ServerListManager 这个类是用来存放及解析目标服务的IP相关的处理
ServerListManager 的构造方法,解析nacosConfig传入的属性,对IP的和端口的解析。
如果SERVER_ADDR没有指定端口则调用ParamUtil.getDefaultServerPort获取默认的端口。
publishConfig里面最后会调用ServerHttpAgent.httpPost()方法将配置推送到nacos
在getCurrentServerAddr中获取目标服务的IP和端口等的相关配置
**