赞
踩
上一篇介绍了如何《使用Sentinel实现gateway网关及服务接口限流》,相信大家已经学会在Spring Cloud Alibaba的整合封装之下,如何将Sentinel整合到Spring Cloud应用中。但是,细心的人,就会发现Sentinel Dashboard控制台中设置的限流规则,在应用重启之后就丢失了,所以需要将Sentinel的规则持久化。
Sentinel 的理念是开发者只需要关注资源的定义,当资源定义成功后可以动态增加各种流控降级规则。Sentinel 提供两种方式修改规则:
loadRules
)DataSource
适配不同数据源修改手动通过 API 修改比较直观,可以通过以下几个 API 修改不同的规则:
- FlowRuleManager.loadRules(List<FlowRule> rules); // 修改流控规则
- DegradeRuleManager.loadRules(List<DegradeRule> rules); // 修改降级规则
手动修改规则(硬编码方式)一般仅用于测试和演示,生产上一般通过动态规则源的方式来动态管理规则。
一般来说,规则的推送有下面三种模式:
推送模式 | 说明 | 优点 | 缺点 |
---|---|---|---|
原始模式 | API 将规则推送至客户端并直接更新到内存中,扩展写数据源(WritableDataSource ) | 简单,无任何依赖 | 不保证一致性;规则保存在内存中,重启即消失。严重不建议用于生产环境 |
Pull 模式 | 扩展写数据源(WritableDataSource ), 客户端主动向某个规则管理中心定期轮询拉取规则,这个规则中心可以是 RDBMS、文件 等 | 简单,无任何依赖;规则持久化 | 不保证一致性;实时性不保证,拉取过于频繁也可能会有性能问题。 |
Push 模式 | 扩展读数据源(ReadableDataSource ),规则中心统一推送,客户端通过注册监听器的方式时刻监听变化,比如使用 Nacos、Zookeeper 等配置中心。这种方式有更好的实时性和一致性保证。生产环境下一般采用 push 模式的数据源。 | 规则持久化;一致性;快速 | 引入第三方依赖 |
上述 loadRules()
方法只接受内存态的规则对象,但更多时候规则存储在文件、数据库或者配置中心当中。DataSource
接口给我们提供了对接任意配置源的能力。相比直接通过 API 修改规则,实现 DataSource
接口是更加可靠的做法。
生产环境下一般更常用的是 push 模式的数据源。对于 push 模式的数据源,如远程配置中心(ZooKeeper, Nacos, Apollo等等),推送的操作不应由 Sentinel 客户端进行,而应该经控制台统一进行管理,直接进行推送,数据源仅负责获取配置中心推送的配置并更新到本地。因此推送规则正确做法应该是 配置中心控制台/Sentinel 控制台 → 配置中心 → Sentinel 数据源 → Sentinel,而不是经 Sentinel 数据源推送至配置中心。这样的流程就非常清晰了:
DataSource
扩展常见的实现方式有:
Sentinel 目前支持以下数据源扩展:
详细说明,可参考官网:
https://github.com/alibaba/Sentinel/wiki/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%99%E6%89%A9%E5%B1%95
通过上一节,我们已经将Sentinel整合进SpringCloud应用及网关。
下面我们将同时使用到Nacos
和Sentinel Dashboard
,所以可以先把Nacos
和Sentinel Dashboard
启动起来。
默认配置下启动后,它们的访问地址(后续会用到)为:
在上一节的service-order的Spring Cloud应用的pom.xml
中引入Spring Cloud Alibaba的Sentinel模块和Nacos存储扩展:
- <dependency>
- <groupId>com.alibaba.cloud</groupId>
- <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
- </dependency>
-
- <dependency>
- <groupId>com.alibaba.csp</groupId>
- <artifactId>sentinel-datasource-nacos</artifactId>
- </dependency>
-
- <dependency>
- <groupId>com.alibaba.cloud</groupId>
- <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
- </dependency>
-
- <dependency>
- <groupId>com.alibaba.cloud</groupId>
- <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
- </dependency>
- #开启sentinel
- feign.sentinel.enabled=true
- spring.cloud.sentinel.transport.port=8719
- #sentinel控制台
- spring.cloud.sentinel.transport.dashboard=localhost:8080
- #服务启动直接建立心跳连接
- spring.cloud.sentinel.eager=true
-
- #Sentinel使用Nacos存储规则
- spring.cloud.sentinel.datasource.ds1.nacos.server-addr=192.168.100.80:8848
- spring.cloud.sentinel.datasource.ds1.nacos.dataId=${spring.application.name}-flow-rules
- spring.cloud.sentinel.datasource.ds1.nacos.groupId=myGroupId
- spring.cloud.sentinel.datasource.ds1.nacos.namespace=@namespace@
- spring.cloud.sentinel.datasource.ds1.nacos.data-type=json
- spring.cloud.sentinel.datasource.ds1.nacos.rule-type=flow
注:如果你的Nacos配置了不同的隔离环境 namespace,则需要指定具体哪一个namespace,否则会加载不到规则配置,报错如下:
[c.a.c.s.datasource.converter.SentinelConverter ] line 80 : converter can not convert rules because source is empty
naocs 如下:
spring.cloud.sentinel.transport.dashboard
:sentinel dashboard的访问地址,根据上面准备工作中启动的实例配置spring.cloud.sentinel.datasource.ds.nacos.server-addr
:nacos的访问地址,,根据上面准备工作中启动的实例配置spring.cloud.sentinel.datasource.ds.nacos.groupId
:nacos中存储规则的groupIdspring.cloud.sentinel.datasource.ds.nacos.dataId
:nacos中存储规则的dataIdspring.cloud.sentinel.datasource.ds.nacos.rule-type
:该参数是spring cloud alibaba升级到0.2.2之后增加的配置,用来定义存储的规则类型。所有的规则类型可查看枚举类:org.springframework.cloud.alibaba.sentinel.datasource.RuleType
,每种规则的定义格式可以通过各枚举值中定义的规则对象来查看,比如限流规则可查看:com.alibaba.csp.sentinel.slots.block.flow.FlowRule
这里对于dataId使用了${spring.application.name}
变量,这样可以根据应用名来区分不同的规则配置。
在Nacos控制台,对应的namespace ,新建一个json配置文件:service-order-flow-rules,如下:
其中:Data ID
、Group
就是上面第5点中配置的内容。配置格式选择JSON,并在配置内容中填入下面的内容:
- [
- {
- "resource": "/test",
- "limitApp": "default",
- "grade": 1,
- "count": 10,
- "strategy": 0,
- "controlBehavior": 0,
- "clusterMode": false
- }
- ]
可以看到上面配置规则是一个数组类型,数组中的每个对象是针对每一个保护资源的配置对象,每个对象中的属性解释如下:
0
代表根据并发数量来限流,1
代表根据QPS来进行流量控制启动service-order 应用,注册到nacos到,打开Sentinel控制台,可以看到上面nacos新建的限流规则,如下:
注意:
在完成了上面的整合之后,对于接口流控规则的修改就存在两个地方了:Sentinel控制台、Nacos控制台。
这个时候,通过Nacos修改该条规则是可以同步到Sentinel的,但是通过Sentinel控制台修改或新增却不可以同步到Nacos。因为当前版本的Sentinel控制台不具备同步修改Nacos配置的能力,而Nacos由于可以通过在客户端中使用Listener来实现自动更新。所以,在整合了Nacos做规则存储之后,需要知道在下面两个地方修改存在不同的效果:
下面我们进通过修改,使得Nacos与Sentinel可以互相同步限流规则:
要通过 Sentinel 控制台配置集群流控规则,需要对控制台进行改造。主要改造规则可以参考:
https://github.com/alibaba/Sentinel/wiki/Sentinel-控制台(集群流控管理)#规则配置
其控制台推送规则:
控制台监听Nacos配置变化,如发生变化就更新本地缓存。从而让控制台本地缓存总是和Nacos一致。
2.1 通关git官网下载Sentinel 源代码,如下:
https://github.com/alibaba/Sentinel/archive/1.7.2.zip
下载后解压,使用IDEA打开如下:
2.2 修改sentinel-dashboard 控制台模块的pom.xml,将<scope>test</scope>注释掉
- <dependency>
- <groupId>com.alibaba.csp</groupId>
- <artifactId>sentinel-datasource-nacos</artifactId>
- <!--<scope>test</scope>-->
- </dependency>
2.3 修改sidebar.html页面(sentinel控制台左边菜单栏)
sentinel-dashboard/src/main/webapp/resources/app/scripts/directives/sidebar.html
并找到如下代码段后,并把注释打开,名称也稍作修改。
修改前:
修改后:
2.4 修改nacos相关java代码
找到如下目录(位于test目录)
sentinel-dashboard/src/test/java/com/alibaba/csp/sentinel/dashboard/rule/nacos
将整个目录拷贝到
sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/rule/nacos
修改com.alibaba.csp.sentinel.dashboard.controller.v2.FlowControllerV2.java
修改如下:
其中,注入的两个bean:
FlowRuleNacosProvider.java 如下,无需修改
getRules
方法中的appName
参数是Sentinel中的服务名称。configService.getConfig
方法是从Nacos中获取配置信息的具体操作。其中,DataId和GroupId分别对应客户端使用时候的对应配置。如下:- spring.cloud.sentinel.datasource.ds1.nacos.server-addr=192.168.100.80:8848
- spring.cloud.sentinel.datasource.ds1.nacos.dataId=${spring.application.name}-flow-rules
FlowRuleNacosPublisher.java如下,无需修改:
打开 NacosConfigUtil.java ,如下两个地方,需要和上面使用nacos存储时的配置一致。注意:两边的DataId和GroupId必须对应上。
打开 NacosConfig.java,修改如下,主要是nacos配置中心的地址与namespace隔离环境的配置修改,如果没有设置namespace,就可以不设置 PropertyKeyConst.NAMESPACE 。
经过以上步骤就已经把流控规则改造成推模式持久化了。
2.5 编译生成jar包
执行命令
mvn clean package -DskipTests
编译成功后,在项目的 target 目录可以找到sentinel-dashboard.jar ,执行以下命令可以启动控制台:
java -jar sentinel-dashboard.jar
打开Sentinel控制台,可以看到上面通过nacos新建的限流规则
我们可以尝试在Sentinel控制台修改该规则,看是否能同步推送到Nacos,这里我们修改阈值为15,打开Nacos配置中心,可以看到已经更新过来了。
下面我们通过修改Nacos将阈值再修改为20,刷新Sentinel,也能同步过来,如下:
通过测试发现,在Sentinel控制台修改规则可以同步到Nacos,或者在Nacos上修改规则也可以同步到Sentinel控制台。
参考:
●阿里巴巴为什么能抗住90秒100亿?--服务端高并发分布式架构演进之路
●SpringCloud电商秒杀微服务-Redisson分布式锁方案
查看更多好文,进入公众号--撩我--往期精彩
一只 有深度 有灵魂 的公众号0.0
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。