前言
经过上一章java系列 SpringCloudAlibaba组件 -Sentinel讲解我们已经对sentinel的各项规则控制以及资源管控都已经熟练掌握了,但是在使用过程中大家肯定发现,我们配置好的流控或者降级等一系列规则之后当我们重启项目或者项目迭代的时会发现我们配置的所有规则都会丢失,原因是因为sentinel他默认是将规则存储在内存中的并不会将规则持久化,那我们这一章主要就是讲解如何给sentinel配置一个新的规则源,避免将规则储存到内存中,保证我们每次项目迭代不需要重新配置控流规则!
在sentinel文档中提到了sentinel的持久化支持很多存储服务
那我们为什么要选择nacos呢?
- 因为如果当我们项目没有上线之前就要对项目中的资源进行限流配置,那我们肯定需要一个较好的图形化界面去进行配置,以降低我们的配置的难度以及便利性,那其中我们可以知道nacos他是有很好的图形管理界面的
- 这也是最关键的一点,就是从上述的图中我们可以看见sentinel他支持两种规则持久化模式,第一种就是拉模式第二种是推模式,可以理解一下,对于限流规则我们肯定希望他可以及时生效所以我们也就排除了拉模式的那些数据源,然后我们可以看见推模式也是提供了很多数据源,我们可以思考一下,如果你要选择推模式是不是需要我们的项目去时刻监听数据源的变动,当数据源发生变动以后对我们配置的规则进行一个统一推送的,那你们发现在推模式中redis和zookeeper他们的监听逻辑异常麻烦而且还要处理很多问题,而nacos他自带有一套完善的监听系统供我们使用,而且他还是SpringCloud中的一个非常重要的服务中心组件,所以我们项目肯定是离不开他的,所以我分析下来,Nacos也就最适合作为Sentinel的数据源,然后对Sentinel中配置的所有规则进行一个持久化保存!
如果你还不懂nacos或者不会使用nacos作为你项目的配置中心的话可以看我这篇文章-java系列 SpringCloudAlibaba组件 – Nacos
单向同步
持久化具体流程也就是将限流规则以配置文件的方式存在nacos中,然后当我们微服务启动以后微服务就会向nacos去读取这些配置文件,然后再向sentinel控制台推送一份以便于展示,但是注意了 : 该方法如果你通过sentinel控制台修改了限流规则后他并不会同步到nacos配置中心,也就是说你通过sentinel控制台修改的限流规则在微服务重启之后也都会被清除掉!这也是这个方法的弊端,只能单向同步但是好处就在于简单,具体情况我们会在双向同步中叙述!
首先我们先导入一个pom依赖,当我们将限流规则配置到nacos的配置中时,sentinel控制台也可以看见该规则,版本号和你的sentinel同版本
<!--sentinel集成nacos-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<version>1.8.0</version>
</dependency>
微服务配置Sentinel规则源
首先我们就需要先配置一下sentinel的限流配置在nacos的位置,当我们微服务启动以后就会在nacos中读取sentinel的限流配置并执行,具体配置文件整体如下,大家也可以直接copy过来使用
spring:
cloud:
nacos:
discovery:
server-addr: ip:10010 # nacos ip地址:端口号
username: nacos #nacos的账号
password: nacos #nacos的密码
# namespace: 6d950d5e-e66f-4594-8917-179408dbeb3b
sentinel:
transport:
port: 8719 #sentinel客户端与控制台通讯端口,当被占用时会向上兼容,使用8720端口
dashboard: ip:12000 #sentinel控制台ip:端口号
eager: true #启动是否自动注册,如果为false,只有当该微服务有请求时才会注册到sentinel
datasource:
# nacos中流控规则的配置文件
flow: #这个随便填即可,不要和下面的命名冲突就行
nacos: #使用nacos为数据源
server-addr: ip:10010 #nacos的ip:端口号
data_id: goods-flow #nacos中流控配置文件的data_id
group_id: SENTINEL_GROUP #nacos中流控配置文件的分组,我们这里为了方便管理配置文件,我们将所有配置文件都放到SENTINTL分组下
rule-type: flow #规则模式 flow-流控 degrade-降级 system-系统 param-flow-热点规则 authority-授权
username: nacos #nacos账号
password: nacos #nacos密码
#为了方便演示我们这里就不使用namespace进行环境隔离了,要不每一份配置和微服务的namespace进行对应
#namespace: 6d950d5e-e66f-4594-8917-179408dbeb3b
# nacos中降级规则的配置文件
degrade:
nacos:
server-addr: ip:10010
data_id: goods-degrade
group_id: SENTINEL_GROUP
rule-type: degrade
username: nacos
password: nacos
# nacos中系统规则的配置文件
system:
nacos:
server-addr: ip:10010
data_id: goods-system
group_id: SENTINEL_GROUP
rule-type: system
username: nacos
password: nacos
# 热点参数限流规则
param-flow:
nacos:
server-addr: ip:10010
data_id: goods-param-flow
group_id: SENTINEL_GROUP
rule-type: param-flow
username: nacos
password: nacos
# nacos中授权规则的配置文件
authority:
nacos:
server-addr: ip:10010
data_id: goods-authority
group_id: SENTINEL_GROUP
rule-type: authority
username: nacos
password: nacos
关于rele-type的参数在com.alibaba.cloud.sentinel.datasource.RuleType源码包中有展示
创建Sentinel规则配置
然后我们去nacos根据上述配置指向创建好指定的配置文件
切记 : 如果要copy以下配置文件需要将其中的注释都清除掉,要不会报错
流控规则配置
根据application中的配置进行配置文件创建
具体配置内容中参数的意思如下
- resource : 资源名,即限流规则的作用对象
- limitApp : 流控针对的调用来源,若为default的话,则不区分调用来源
- grade : 限流阈值类型;0代表根据并发量限流,1代表QPS来进行流量控制
- count : 限流阈值
- strategt : 流控模式,调用关系限流策略
- controlBehavior : 流量控制效果;0代表快速失败,1代表Warm UP,2代表排队等待
- clustreMode : 是否为集群模式
- warmUpPeriodSec : 预热时长 , 当流控效果为Warm UP才需要填
- maxQueueingTimeMs : 超时时长, 当流控效果为排队等待 才需要填
具体配置如下
[
{
"resource":"/goods/findGoods",
"limitApp":"default",
"grade":1,
"count":1,
"strategy":0,
"controlBehavior":0,
"warmUpPeriodSec":10,
"maxQueueingTimeMs":500,
"clusterMode":false
}
]
启动服务以后去sentinel控制台查看就会发现sentinel根据nacos配置中心的配置创建了一个流控规则
降级规则配置
也是先根据application中的配置信息去nacos中创建配置,降级一共有3中熔断策略,他们的配置信息中一样的参数但是代表的意思却不太一样,配置具体如下
[
{
//资源名
"resource":"/goods/findGoods",
//熔断策略 - 慢调用比例
"grade":0,
//最大RT
"count":1,
//比例阈值
"slowRatioThreshold":0.1,
//熔断时长
"timeWindow":2,
//最小请求数
"minRequestAmount":5
},
{
//资源名
"resource":"/goods/testA",
//熔断策略 - 异常比例
"grade":1,
//比例阈值
"count":1,
//熔断时长
"timeWindow":2,
//最小请求数
"minRequestAmount":5
},
{
//资源名
"resource":"/goods/testB",
//熔断策略 - 异常数
"grade":2,
//异常数
"count":3,
//熔断时长
"timeWindow":2,
//最小请求数
"minRequestAmount":5
}
]
如count这个参数 , 在熔断策略为慢调用比例时他含义是 最大RT(响应时间),而熔断策略为异常比例时他的含义是比例阈值,这里大家要注意!
然后我们重启goods微服务,我们就可以在sentinel控制台看见我们配置的降级规则了
热点参数限流规则配置
[
{
//资源名
"resource":"/goods/findGoods",
//限流模式 1=QPS
"grade":1,
//参数索引
"paramIdx":1,
//单机阈值
"count":2,
//统计窗口时长
"durationInSec":4,
//参数集合
"paramFlowItemList":[
{
//参数值
"object":"123456",
//限流阈值
"count":1,
//参数类型
"classType":"java.lang.String"
}
],
//是否集群
"clusterMode":false
}
]
系统规则配置
[
{
"highestSystemLoad":1.0,
"highestCpuUsage":0.2,
"qps":3.0,
"avgRt":4,
"maxThread":5
}
]
对应的会在sentinel中创建以下规则
授权规则配置
对应的会在sentinel中创建以下配置
[
{
//资源名
"resource":"/goods/findGoods",
//流控应用
"limitApp":"sem",
//0.白名单 1.黑名单
"strategy":0
}
]
双向同步
上面我们提到了单向同步的问题,就是当我们想要持久性的修改限流规则的时候我们只能去修改nacos配置中心,我们在sentinel中修改和增加的限流规则在项目重启后都会被清除,,那sentinel也就是几乎做了一个展示规则的作用,
双向同步就如上图所示 : 你在sentinel控制台修改限流规则后他会推送到nacos中,然后再推送给各个微服务中去进行执行,那我们如何可以通过修改sentinel控制台然后同步到nacos的配置中心呢,
遗憾的是sentinel对这一块并没有开源但是他留有一个口子,我们可以通过这个口子去修改源码然后将流控规则进行双向同步,其他的规则则需要我们自己去实现接口,网上也有好多大神去实现了但是毕竟都是我们自己实现的,如果大家想要将双向同步运用在开发环境的话我推荐 要不用阿里云商业版sentinel,因为商业版sentinel带有双向同步,要不就只将流控规则来进行双向同步其他规则还是使用第一种老办法进行单向同步,因为网上修改源代码实现双向同步的都是测试和学习用的,一般不推荐大家去运用到线上,就算运用到线上也需要自己认真的检查代码后再实施!
接下来我就叙述一下如何通过sentinel留下的一个口子来实现流控规则的双向同步
首先我们需要将github上的sentinel的源代码拉下来,我这里使用的是1.8.0的大家根据自己使用的版本进行下载源代码改造
拉下来以后我们首先先修改sentinel-dashboaed子项目的pom包
把那个test去掉也就是修改成以下
然后我们把test文件夹下的rule - nacos这个文件夹复制到 main - java - com - alibaba -csp -sentinel -dashboard -rule文件夹下,如下图所示
复制过去以后我们首先先修改nacos文件夹下的NacosConfig,改造详情如下
我示例中没有使用到nacos的namespace和集群,如果大家使用到了那这两个参数也需要填进去,然后我们在去修改配置文件将这些变量参数的值添加到配置文件中,因为我服务器nacos默认端口号8848被占用了,所以我的nacos部署的端口号为10010!
然后我们再去修改一个controller层下FlowControllerV2,修改示例如下
然后我们去修改一个web页面,让持久化流控规则显示菜单显示出来,在webapp包下面
放开注释以后,我们就可以将这个改过得到sentinel控制台打包了
然后我们将打好的包复制到我们的服务器中,
然后启动!记得关闭了旧的sentinel,启动命令如下,我这里sentinel端口号设置为了12000,大家根据自身情况来设置
nohup java -Dserver.port=12000 -Dcsp.sentinel.dashboard.server=localhost:12000 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar >> ./sentinel1.log &
然后我们再去浏览器请求 ip:12000 , 账号密码还是sentinel的默认账号密码 都是 sentinel
发现启动成功了,然后我们再去启动我们的微服务,
微服务监听成功以后,我们可以发现多了一个菜单[流控规则V1],这个就是我们修改源代码新增的一个菜单,这里面展示和创建的规则都会同步到nacos中,我们可以先来测试一下,我们先测试一下在nacos中新增配置会不会同步到sentinel控制台的流控规则V1里面
首先我们现在nacos中新增一个配置 goods-flow-rules
注意 : 命名规范应该是 [服务名]-flow-rules , 必须是这样子的命名规范,因为sentinel的流控规则V1默认读取就是这个命名规范!
然后我们去修改我们微服务中关联sentinel流控规则的配置项,以保证我们的微服务可以准确的读取到nacos中存储的流控规则
然后我们重启一下微服务,再去观察sentinel的流控规则V1
就会发现多了一条流控规则,如果没有出现,那八成就是你nacos中命名规则有问题了,那在流控规则V1菜单中修改该条规则就会同步到nacos中,我们可以试一下,我们现在流控规则的阈值为1,那我们改成8,然后去nacos中看goods-flow-rules配置,看看是否修改了
可以发现nacos中配置中阈值(count)也随着变成了8,那流控规则也就实现了双向同步!
如果其他规则也要实现双向同步,推荐大家去直接使用阿里云的商业版sentinel,具体操作的官方文档 : https://github.com/alibaba/Sentinel/wiki/AHAS-Sentinel-%E6%8E%A7%E5%88%B6%E5%8F%B0