Sentinel集成Nacos实现动态流控规则

时间:2023-11-21 10:35:06  热度:0°C
  • 通过FlowRuleManager/loadRules()手动加载流控规则。

  • 在Sentinel Dashboard上针对资源动态创建流控规则。

针对第一种方式,如果接入Sentinel Dashboard,那么同样支持动态修改流控规则,但是基于Sentinel Dashboard所配置的流控规则,都是保存在内存中的,一旦应用重启,这些规则都会被清除。为了解决这个问题,Sentinel提供了动态数据源支持。

目前,Sentinel支持Consul、Zookeeper、Redis、Nacos、Apollo、etcd等数据源的扩展,接下来通过一个案例展示Spring Cloud Sentinel集成Nacos实现动态流控规则,步骤如下:

1/ 添加Nacos数据源的依赖包

</dependency>/ </groupId>/com/alibaba/csp<//groupId>/ </artifactId>/sentinel-datasource-nacos<//artifactId>/ </version>/1/7/0<//version>/<//dependency>/

2/ 创建一个REST接口,用于测试

@RestControllerpublic class DynamicController { @GetMapping( /dynamic ) public String dynamic() { return Hello Dynamic Rules / }}

3/ 在application/yml文件中添加数据源配置

spring/ application/ name/ sentinel-spring-cloud-demo cloud/ sentinel/ transport/ dashboard/ 192/168/56/1/7777 datasource/ - nacos/ server-addr/ 192/168/56/1/8848 data-id/ ${spring/application/name}-sentinel group-id/ DEFAULT_GROUP data-type/ json rule-type/ flow

部分配置说明如下:

  • datasource/ 目前支持redis、apollo、zk、file、nacos,选什么类型的数据源就配置相应的key即可。

  • data-id:可以设置成${spring/application/name},方便区分不同应用的配置。

  • rule-type:表示数据源中规则属于哪种类型,如flow、degrade、param-flow、gw-flow等。

  • data-type:指配置项的内容格式,Spring Cloud Alibaba Sentinel提供了JSON和XML两种格式,如需要自定义,则可以将值配置为custom,并配置converter-class指向converter类。

4/ ***Nacos控制台,创建流控配置规则:

5/ ***Sentinel Dashboard,找到执行项目名称菜单下的“流控规则”,就可以看到在Nacos上所配置的流控规则已经被加载了。

6/ 当我们在Nacos的控制台上修改流控规则后,可以同步的在Sentinel Dashboard上看到流控规则的变化。

那么问题就来了,Nacos其实应该作为一个流控规则的持久化平台,正常的操作过程应该是在Sentinel Dashboard上修改流控规则,然后同步到Nacos上,但是遗憾的是,目前Sentinel Dashboard并不支持该功能。

所以,Nacos名义上是 Datasource ,实际上充当的仍然是配置中心的角色,开发者可以在Nacos控制台上动态修改流控规则并实现规则同步。在实际开发中,很难避免在不清楚情况的情况下,部分开发者使用Sentinel Dashboard来管理流控规则,部分开发者通过Nacos来管理流控规则,这可能导致非常严重的问题。

要想使用Sentinel Dashboard来统一管理流控规则并同步到Nacos上,我们可以自己来实现。

Sentinel Dashboard集成Nacos实现规则同步

Sentinel Dashboard的流控规则下的所有操作,都会调用Sentinel-Dashboard源码中的FlowControllerV1类,这个类中包含流控规则本地化 的CRUD操作。

另外,在com/alibaba/csp/sentinel/dashboard/controller/v2包下存在一个FlowControllerV2类,这个类同样提供流控规则的CRUD,和V1版本不同的是,它可以实现指定数据源的规则拉取和发布。

@RestController@RequestMapping(value = /v2/flow )public class FlowControllerV2 { private final Logger logger = LoggerFactory/getLogger(FlowControllerV2/class)/ @Autowired private InMemoryRuleRepositoryAdapter</FlowRuleEntity>/ repository/ @Autowired @Qualifier( flowRuleDefaultProvider ) private DynamicRuleProvider</List</FlowRuleEntity>/>/ ruleProvider/ @Autowired @Qualifier( flowRuleDefaultPublisher ) private DynamicRulePublisher</List</FlowRuleEntity>/>/ rulePublisher/

FlowControllerV2依赖以下两个非常重要的类:

  • DynamicRuleProvider/ 动态规则的拉取,从指定数据源中获取流控规则后在Sentinel Dashboard中展示。

  • DynamicRulePublisher/ 动态规则的发布,将在Sentinel Dashboard中修改的规则同步到指定数据源中。

我们可以扩展这两个类,然后集成Nacos来实现Sentinel Dashboard规则的同步。

Sentinel Dashboard源码修改

修改Sentinel Dashboard的源码,具体实现步骤如下:

1/ 在GitHub中下载Sentinel Dashboard 1/7/1的源码。

2/ 使用IDEA工具打开sentinel-dashboard工程。

3/ 在pom/xml中把sentinel-datasource-nacos依赖的</scope>/注释掉。

</!-- for Nacos rule publisher sample -->/</dependency>/ </groupId>/com/alibaba/csp<//groupId>/ </artifactId>/sentinel-datasource-nacos<//artifactId>/ </!--</scope>/test<//scope>/-->/<//dependency>/

4/ 修改resources/app/scripts/directives/sidebar/sidebar/html文件中下面这段代码,将dashboard/flowV1改成dashboard/flow,也就是去掉V1。修改之后,会调用FlowControllerV2中的接口。

</li ui-sref-active= active ng-if= !entry/isGateway >/ </!--</a ui-sref= dashboard/flowV1({app/ entry/app}) >/-->/ </a ui-sref= dashboard/flow({app/ entry/app}) >/ </i class= glyphicon glyphicon-filter >/<//i>/&/nbsp/&/nbsp/流控规则<//a>/<//li>/

5/ 在com/alibaba/csp/sentinel/dashboard/rule包中创建一个Nacos包,并创建一个类用来加载外部化配置。

@ConfigurationProperties(prefix = sentinel/nacos )public class NacosPropertiesConfiguration { private String serverAddr/ private String dataId/ private String groupId = DEFAULT_GROUP / private String namespace/ // 省略get/set方法}

6/ 创建一个Nacos配置类NacosConfiguration

@EnableConfigurationProperties(NacosPropertiesConfiguration/class)@Configurationpublic class NacosConfiguration { @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(NacosPropertiesConfiguration nacosPropertiesConfiguration) throws NacosException { Properties properties = new Properties()/ properties/put(PropertyKeyConst/SERVER_ADDR/ nacosPropertiesConfiguration/getServerAddr())/ properties/put(PropertyKeyConst/NAMESPACE/ nacosPropertiesConfiguration/getNamespace())/ return ConfigFactory/createConfigService(properties)/ }}

7/ 创建一个常量类NacosConstants,分别表示默认的GROUP_ID和DATA_ID的后缀

public class NacosConstants { public static final String DATA_ID_POSTFIX = -sentinel-flow / public static final String GROUP_ID = DEFAULT_GROUP /}

8/ 实现动态从Nacos配置中心获取流控规则

@Servicepublic class FlowRuleNacosProvider implements DynamicRuleProvider</List</FlowRuleEntity>/>/ { private static final Logger logger = LoggerFactory/getLogger(FlowRuleNacosProvider/class)/ @Autowired private NacosPropertiesConfiguration nacosPropertiesConfiguration/ @Autowired private ConfigService configService/ @Autowired private Converter</String/ List</FlowRuleEntity>/>/ converter/ @Override public List</FlowRuleEntity>/ getRules(String appName) throws Exception { String dataId = new StringBuilder(appName)/append(NacosConstants/DATA_ID_POSTFIX)/toString()/ String rules = configService/getConfig(dataId/ nacosPropertiesConfiguration/getGroupId()/ 3000)/ logger/info( pull flow rule from Nacos Config/ {} / rules)/ if (StringUtils/isEmpty(rules)) { return new ArrayList</>/()/ } return converter/convert(rules)/ }}

9/ 创建一个流控规则发布类,在Sentinel Dashboard上修改完配置后,需要调用该发布方法将数据持久化到Nacos中。

@Servicepublic class FlowRuleNacosPublisher implements DynamicRulePublisher</List</FlowRuleEntity>/>/ { @Autowired private NacosPropertiesConfiguration nacosPropertiesConfiguration/ @Autowired private ConfigService configService/ @Autowired private Converter</List</FlowRuleEntity>// String>/ converter/ @Override public void publish(String app/ List</FlowRuleEntity>/ rules) throws Exception { AssertUtil/notEmpty(app/ app cannot be empty )/ if (rules == null) { return/ } String dataId = new StringBuilder(app)/append(NacosConstants/DATA_ID_POSTFIX)/toString()/ configService/publishConfig(dataId/ nacosPropertiesConfiguration/getGroupId()/ converter/convert(rules))/ }}

10/ 修改FlowControllerV2类,将上面配置的两个类注入进来,表示规则的拉取和规则的发布统一用我们前面定义的两个实例,然后将FlowControllerV2这个类中的代码覆盖FlowControllerV1的代码

@RestController@RequestMapping(value = /v2/flow )public class FlowControllerV2 { private final Logger logger = LoggerFactory/getLogger(FlowControllerV2/class)/ @Autowired private InMemoryRuleRepositoryAdapter</FlowRuleEntity>/ repository/ @Autowired @Qualifier( flowRuleNacosProvider ) private DynamicRuleProvider</List</FlowRuleEntity>/>/ ruleProvider/ @Autowired @Qualifier( flowRuleNacosPublisher ) private DynamicRulePublisher</List</FlowRuleEntity>/>/ rulePublisher/

11/ 在application/properties文件中添加Nacos服务端的配置信息

sentinel/nacos/serverAddr=192/168/56/1/8848sentinel/nacos/namespacec=sentinel/nacos/group-id=DEFAULT_GROUP

12/ 使用下面命令将代码打包成一个 fat jar,然后启动。

mvn clean package
Sentinel Dashboard规则数据同步

对于应用程序来说,需要改动的地方比较少,只需要注意配置文件中的data-id的命名要以-sentinel-flow结尾即可,因为在sentinel dashboard中我们写了一个固定的后缀。

spring/ application/ name/ spring-cloud-sentinel-dynamic cloud/ sentinel/ transport/ dashboard/ 192/168/56/1/7777 datasource/ - nacos/ server-addr/ 192/168/56/1/8848 data-id/ ${spring/application/name}-sentinel-flow group-id/ DEFAULT_GROUP data-type/ json rule-type/ flow

1/ ***Sentinel Dashboard,进入“流控规则”,然后针对指定的资源创建流控规则。

2/ 进入Nacos控制台,就可以看到在Sentinel Dashboard中配置的流控规则。

免责声明:
1. 《Sentinel集成Nacos实现动态流控规则》内容来源于互联网,版权归原著者或相关公司所有。
2. 若《83404919文库网》收录的文本内容侵犯了您的权益或隐私,请立即通知我们删除。