SpringCloudAlibaba-服务容错Sentinel(进阶)
一:基本概念
1.1 资源:就是Sentinel要保护的东西,它可以是Java应用程序中的任何内容,可以是一个服务,也可以是一个方法,甚至可以是一段代码
1.2 规则:用来定义如何进行保护资源的
二:重要功能
Sentinel的主要功能就是容错,主要体现在下面三个类型:
2.1 流量控制
流量控制在网络传输中是一个常用的概念,它用于调整网络包的数据。任意时间到来的请求往往是随机不可控的,而系统的处理能力是有限的。我们需要根据系统的处理能力对流量进行控制。
2.2 熔断降级
当检测到调用链路中某个资源出现不稳定的表现,例如请求响应时间长或异常比例升高的时候,则对这个资源的调用进行限制,让请求快速失败,避免影响到其他的资源而导致级联故障。
Sentinel对这个问题采取了两种措施
1:通过并发线程数进行控制
Sentinel通过限制资源并发线程的数量,来减少不稳定资源对其他资源的影响。当某个资源出现不稳定的情况下,例如响应时间变长,对资源的直接影响就是会造成线程数的逐步堆积。当线程数
在特定资源上堆积到一定的数量之后,对该资源的新请求就会被拒绝。堆积的线程完成任务后才开始继续接收请求。
2:通过响应时间对资源进行降级
当依赖的资源出现响应时间过长后,所有对该资源的访问都会被直接拒绝,直到过了指定的时间窗口之后才重新恢复。
2.3 负载均衡保护
当系统负载均衡较高时,如果还持续让请求进入可能会导致系统崩溃,无法响应。在集群环境下,会把本应这台机器承载的流量转发到其他的机器上去。如果这个时候其他的机器也处在一个边缘状态的时候
Sentinel提供了对应的保护机制,让系统的入口流量和系统的负载达到一个平衡,保证系统在能力范围之内处理最多的请求。
三:Sentinel规则
3.1 流控规则
流量控制,其原理是监控应用流量的QPS或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。
第一步:点击簇点链路,我们就可以看到访问过的接口地址,然后点击对应的流控按钮,进入流控规则配置页面。新增流控规则界面如下:
- 资源名:唯一名称,默认是请求路径,可自定义
- 针对来源:指定对哪个微服务进行限流,默认default,意思是不区分来源,全部限制
- 阈值类型\单机阈值:
- QPS(每秒请求数量):当调用接口的QPS达到阈值的时候,进行限流
- 线程数:当调用接口的线程数达到阈值的时候,进行限流
- 是否集群:本例不做集群
上一章文末简单示例就是以QPS来配置的。
3.1.1 配置流控模式
点开高级选项 如下图
可以看到有三种流控模式:直接、关联、链路。接下来我们逐一演示
直接流控模式:最简单的模式,当指定接口到达限流条件时开启限流。参考上章案例
关联流控模式:当指定接口关联的接口达到限流条件时,开启指定接口的限流。
第一步:配置限流规则,将流控模式设置为关联,关联资源设置为/sentinel/mesg2
第二步:通过jemeter访问mesg2,达到限流状态
第三步:访问/sentinel/mesg1,会发现已经被限流
链路流控模式
当从某个接口过来的资源达到限流条件时,开启限流。
配置流控效果
快速失败(默认):直接失败,抛出异常,不做任何额外的处理,是最简单的效果
Warm up:它从开始阈值到最大QPS阈值会有一个缓冲阶段,一开始的阈值是最大QPS阈值的1/3,然后慢慢增长,直到最大阈值,适用于将突然增大的流量转换为缓步增长的场景。
排队等待:让请求以均匀的速度通过,单机阈值为每秒通过数量,其余的排队等待; 它还会让设置一个超时时间,当请求超过超时间时间还未处理,则会被丢弃。
3.2 降级规则:
当满足什么条件的时候,对服务进行降级。Sentinel提供了三个衡量条件:
平均响应时间:当资源的平均响应时间超过阈值(以 ms 为单位)之后,资源进入准降级状态。如果接下来 1s 内持续进入 5 个请求,它们的 RT都持续超过这个阈值,
那么在接下的时间窗口(以 s 为单位)之内,就会对这个方法进行服务降级。
异常比例:当资源的每秒异常总数占通过量的比值超过阈值之后,资源进入降级状态,即在接下来的时间窗口之内,对这个方法的调用都会自动返回。异常比例的阈值范围是[0.0,1.0]
第一步:模拟异常
int i = 0; @RequestMapping("/mesg2") public String message2(){ i++; if(i%3 == 0){ throw new RuntimeException(); } return "message2"; }
第二步:设置异常比例为0.25
3.3 热点规则:
一种更细粒度的流控规则,它允许将规则具体到参数上。
第一步:代码编写
@RequestMapping("/mesg3")
@SentinelResource("mesg3")
public String message3(String name,Integer age){
return "message3="+name+"_"+age;
}
第二步:配置热点规则
第三步:分别用两个参数访问,会发现只对第一个参数限流了
热点key增强使用:参数例外项允许对一个参数的具体值进行流控...(此处不做演示了)
3.4 授权规则:
来源访问控制根据资源的请求来源限制资源 是否通过
若配置白名单,则只有请求来源定位于白名单内时才可通过;
若配置黑名单,则请求来源于黑名单时不通过,其余请求通过;
第一步:自定义来源处理规则
@Component public class RequestOriginParserDefinition implements RequestOriginParser { @Override public String parseOrigin(HttpServletRequest request) { String serviceName = request.getParameter("serviceName"); return serviceName; } }
第二步:配置授权规则
这个配置的意思是只有serviceName=pc不能访问(黑名单)
第三步:访问接口查看效果
3.5 系统规则
系统保护规则是从应用级别的入口流量进行控制,从单台机器的总体 Load、RT、入口 QPS 、CPU使用率和线程数五个维度监控应用数据,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。
系统保护规则是应用整体维度的,而不是资源维度的,并且仅对入口流量 (进入应用的流量) 生效。
- Load(仅对 Linux/Unix-like 机器生效):当系统 load1 超过阈值,且系统当前的并发线程数超过系统容量时才会触发系统保护。系统容量由系统的 maxQps * minRt 计算得出。设定参考值一般是 CPU cores * 2.5。
- RT:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。
- 线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。
- 入口 QPS:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。
- CPU使用率:当单台机器上所有入口流量的 CPU使用率达到阈值即触发系统保护。
四:Feign整合Sentinel
4.1 引入sentinel依赖
<!--sentinel组件--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency>
4.2 application.yml配置中开启Feign对Sentinel的支持
# 开启 Feign 对 Sentinel 的支持 feign: sentinel: enabled: true
4.3 创建容错类
/** * 容错类要求必须实现被容错的接口,并为每个方法实现容错方案 */ @Component @Slf4j public class ProductApiFallback implements ProductApiService { @Override public Product getByPid(Integer pid) { Product product = new Product(); product.setPname("服务容错"); product.setPid(-1); return product; } }
4.4 对feign管理的接口指定容错类
@FeignClient(value = "service-product",fallback = ProductApiFallback.class)//声明调用的提供者的name public interface ProductApiService { /** * 指定调用提供者的哪个方法 * @FeignClient+@GetMapping 就是一个完整的请求路径 http://service-product/product/{pid} * @param pid * @return */ @GetMapping("/product/{pid}") Product getByPid(@PathVariable("pid") Integer pid); }
4.5 停止或异常shop-product服务,请求接口测试