Sentinel
是阿里开源的流量控制框架,从限流、降级、熔断、三个维度保护服务;
基于上游服务和下游服务这一情景&#xff0c;再去了解这三个限流维度&#xff08;维度&#xff1a;限流 <降级 <熔断&#xff09;
&#xff1b;每个服务都是通过接口对外提供服务&#xff0c;客户端请求服务和服务之间的相互调用&#xff0c;当服务的访问流量QPS
到达指定量级就会触发相应的流控规则。
下载地址&#xff1a;https://github.com/alibaba/Sentinel/releases
这里下载了1.7.1
版本的jar
包&#xff0c;下载完直接运行就好&#xff0c;账号密码都是sentinel
。
默认端口是8080
&#xff0c;可以用-Dserver.port&#61;xxxx
指定端口。
访问仪表盘可以看到目前是没有数据的状态&#xff0c;因为还没有任何服务和它交互。
链接&#xff1a;搭建一个Sentinel测试项目
直接在Nacos
上添加配置
custom:info: sentinel-sample provider
custom:info: sentinel-sample consumer
http://localhost:8041/test
http://localhost:8041/getConfig
可以看到Sentinel
仪表盘监控到了访问。组件测试没问题。
链接&#xff1a;流控规则
Sentinel
降级主要有三个策略&#xff1a;RT
、异常比例
、异常数
。
链接&#xff1a;降级规则
前面的流控规则和降级规则都是针对单个资源而言
系统规则则是针对整个应用服务的流量控制规则
它有四种阈值类型&#xff1a;
LOAD
规则只能在Linux
、Unix-like
系统上生效&#xff09;链接&#xff1a;授权规则
前面的Sentinel
常用规则主要是用Sentinel
控制面板上的一些规则、参数去配置限流保护
还有一种能够实现定制化保护&#xff0c;实现更细粒度的规则保护&#xff0c;那就是在代码层面用&#64;SentinelResource
定制自己的流控规则。
说人话&#xff0c;
&#64;SentinelResource
可以贴在接口上面&#xff0c;指定接口限流时做的操作&#xff08;比如自定义返回的提示内容&#xff09;&#xff0c;这样就做到了每个接口都能够有自己的限流提示信息。而不是返回Sentinel
默认的Block By Sentinel(flow limiting)
。
链接&#xff1a;blockHandler属性
链接&#xff1a;热点规则
fallback
属性和上面的blockHandler
属性都是用来指定处理方法的&#xff0c;它指定的是业务代出现异常后的处理方法&#xff0c;当业务报出异常就会进入指定的方法响应请求。
&#64;RequestMapping("/fallBackTest")&#64;SentinelResource(value &#61; "fallBackTest", fallback &#61; "fallBackHandler")public String fallBackTest(String param) {int i &#61; 1 / 0;return "return from fallBackTest";}
异常响应方法
public String fallBackHandler(String param, BlockException blockException) {return "return from customfallBackHandler" &#43; RandomUtils.nextInt();}
因为有int i &#61; 1 / 0
&#xff0c;所以接口必报算术异常&#xff0c;进入fallBackHandler()
方法响应请求。
如果没有生效有可能是版本问题&#xff0c;
1.6.0
之前的版本不能针对业务异常进行处理。
blockHandler
和fallback
属性是可以一起用的&#xff0c;当达到阈值时直接进入blockHandler
指定的限制响应方法&#xff1b;当没有达到阈值&业务出现异常时&#xff0c;直接执行fallback
指定的异常响应方法。
如果有想要忽略的异常不想交由
blockHandler
指定的限制响应方法处理&#xff0c;可以用exceptionsToIgnore
属性指定。
如&#xff1a;&#64;SentinelResource(value &#61; "fallBackTest", fallback &#61; "fallBackHandler",exceptionsToIgnore &#61; {RuntimeException.class})
&#xff0c;表示忽略RuntimeException.class
类型的异常。
在上面对于blockHandler
和fallback
属性的使用&#xff0c;其指定的方法都放在了Controller
中&#xff0c;这样会显得非常凌乱
这时候可以使用另外两个对应的属性fallbackClass
和blockHandlerClass
来优化代码结构。
首先定义fallbackClass
指定的异常响应类&#xff1a;
public class FallBackHandler {public static String fallBackHandler(String param, BlockException blockException) {return "return from customfallBackHandler" &#43; RandomUtils.nextInt();}
}
注意&#xff1a;方法必须用
static
修饰。
同理定义限制响应类
public class CustomBlockHandler {public static String customBlockHandler(String param, BlockException blockException) {return "return from customBlockHandler" &#43; RandomUtils.nextInt();}
}
绑定资源&#xff0c;指定响应类&#xff0c;指定响应方法名
&#64;RequestMapping("/test")&#64;SentinelResource(value &#61; "fallBackTest", blockHandlerClass &#61; {CustomBlockHandler.class},blockHandler &#61; "customBlockHandler",fallbackClass &#61; {FallBackHandler.class},fallback &#61; "fallBackHandler")public String fallBackTest(String param) {int i &#61; 1 / 0;return "return from fallBackTest";}
Sentinel
支持多种持久化方案&#xff1a;
Redis
存储Nacos
存储Zookeeper
存储Apollo
存储因为Nacos
与Sentinel
同属于SpringCloudAlibaba
&#xff0c;因此我选择用nacos
。
配置nacos数据源:
加入nacos
数据源依赖
<dependency><groupId>com.alibaba.cspgroupId><artifactId>sentinel-datasource-nacosartifactId>dependency>
bootstrap.yml
配置文件&#xff08;一下只是修改部分的配置&#xff09;spring:application:name: sentinel-consumer # 应用名cloud:sentinel:transport:port: 8719 # 启动一个端口为8719的 Http Server 与仪表盘进行交互&#xff0c;dashboard: 127.0.0.1:8051 # 仪表盘datasource: # 新增datasource1: # 新增 自定义数据源名字nacos: # 新增 数据源类型server-addr: 124.221.89.200:8848 # 新增 nacos 服务地址dataId: sentinel-consumer-datasource1 # 新增 对应nacos上配置的IDgroupId: DEFAULT_GROUP # 新增 对应nacos上配置所在的组data-tupe: json # 新增 对应nacos上配置的类型rule-type: flow # 新增 flow 表示流控规则
nacos
上添加配置
[{"resource":"/test","limitApp":"default","grade":1,"count":1,"strategy":0,"controlBehavior":0,"clusterMode":false}
]说明&#xff1a;
resource
&#xff1a;资源名称
limitApp
&#xff1a;限制来源
grade
&#xff1a;阈值类型&#xff08;0-线程数
、1-QPS
&#xff09;
count
&#xff1a;阈值
strategy
&#xff1a;流控模式&#xff08;直接、关联、链路&#xff09;
controlBehavior
&#xff1a;流控效果&#xff08;快速失败、Warm Up、排队等待&#xff09;
clusterMode
&#xff1a;是否集群
对应的
Bean
类为com.alibaba.csp.sentinel.slots.block.flow.FlowRule
public class FlowRule extends AbstractRule {private int grade &#61; 1;private double count;private int strategy &#61; 0;private String refResource;private int controlBehavior &#61; 0;private int warmUpPeriodSec &#61; 10;private int maxQueueingTimeMs &#61; 500;private boolean clusterMode;private ClusterFlowConfig clusterConfig;private TrafficShapingController controller;...
}
这样子无论是重启Sentinel
控制台还是重启应用服务
都不会丢失流控设置。
上面配置了一个流控规则的持久化库
现在配置一个降级规则的持久化库&#xff0c;因为已经导入依赖了&#xff0c;直接加配一个数据源即可
bootstrap.yml
配置文件&#xff08;一下只是修改部分&#xff09;spring:application:name: sentinel-consumer # 应用名cloud:sentinel:transport:port: 8719 # 启动一个端口为8719的 Http Server 与仪表盘进行交互&#xff0c;dashboard: 127.0.0.1:8051 # 仪表盘datasource:datasource1:nacos:server-addr: 124.221.89.200:8848dataId: sentinel-consumer-datasource1groupId: DEFAULT_GROUPdata-tupe: jsonrule-type: flowdatasource2: # 新增nacos: # 新增server-addr: 124.221.89.200:8848 # 新增dataId: sentinel-consumer-datasource2 # 新增groupId: DEFAULT_GROUP # 新增data-tupe: json # 新增rule-type: degrade # 新增 degrade 表示降级规则
nacos
上添加配置[{"resource":"/test","limitApp":"default","grade":2,"count":1,"timeWindow":3}
]
timeWindow
&#xff1a;时间窗口
这样降级数据源也配置好了
对应的
Bean
类为com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule
public class DegradeRule extends AbstractRule {private int grade &#61; 0;private double count;private int timeWindow;private int minRequestAmount &#61; 5;private double slowRatioThreshold &#61; 1.0D;private int statIntervalMs &#61; 1000;...
}
一样的&#xff0c;也是在bootstrap.yml
配置文件中新配置一个数据源
spring:application:name: sentinel-consumer # 应用名cloud:sentinel:transport:port: 8719 # 启动一个端口为8719的 Http Server 与仪表盘进行交互&#xff0c;dashboard: 127.0.0.1:8051 # 仪表盘datasource:datasource1:nacos:server-addr: 124.221.89.200:8848dataId: sentinel-consumer-datasource1groupId: DEFAULT_GROUPdata-tupe: jsonrule-type: flowdatasource2:nacos:server-addr: 124.221.89.200:8848dataId: sentinel-consumer-datasource2groupId: DEFAULT_GROUPdata-tupe: jsonrule-type: degradedatasource3: # 新增nacos: # 新增server-addr: 124.221.89.200:8848 # 新增dataId: sentinel-consumer-datasource3 # 新增groupId: DEFAULT_GROUP # 新增data-tupe: json # 新增 rule-type: system # 新增 system 表示系统规则
nacos
创建对应配置
系统规则属性&#xff1a;
avgRt
&#xff1a;系统平均响应时间
highestCpuUsage
&#xff1a;CPU使用率
highestSystemLoad
&#xff1a;负载
maxThread
&#xff1a;最大业务线程数
qps
&#xff1a;每秒处理请求数
对应的
Bean
为com.alibaba.csp.sentinel.slots.system.SystemRule
public class SystemRule extends AbstractRule {private double highestSystemLoad &#61; -1.0D;private double highestCpuUsage &#61; -1.0D;private double qps &#61; -1.0D;private long avgRt &#61; -1L;private long maxThread &#61; -1L;...
}
持久化注意事项&#xff1a;
Sentinel
的持久化相当于直接从数据源拉取配置创建规则&#xff0c;所以更改Nacos
上的配置Sentinel
规则会即时生效&#xff0c;重启也不会丢失。- 修改
Sentinel
上的配置而没有修改Nacos
数据源上的配置&#xff0c;重启会丢失&#xff0c;因为修改并不会自动同步到Nacos
上。
承上&#xff1a;SpringCloudAlibaba系列微服务搭建笔记二_RestTemplate&#43;Ribbon
启下&#xff1a;待续