概述
文章目录
- 一、为什么需要熔断与服务降级
- 限流的三种思路
- 计数器算法
- 漏桶算法
- 令牌桶算法
- 二、Sentinel 梗概介绍(摘自官方文档)
- 三、项目引入Sentinel
- 4.RestTemplate 支持
- 使用Sentinel控制台进行流控、服务降级
- 流控
- 降级
- 热点数据降级
- 参考文章
一、为什么需要熔断与服务降级
分布式系统中一个微服务需要依赖于很多的其他的服务,那么服务就会不可避免的失败。例如A服务依赖于B、C、D等很多的服务,当B服务不可用的时候,会一直阻塞或者异常,更不会去调用C服务和D服务。同时假设有其他的服务也依赖于B服务,也会碰到同样的问题,这就及有可能导致雪崩效应。
如下案例:一个用户通过通过web容器访问应用,他要先后调用多个模块,但是由于某些原因,导致某个服务不可用,与此同时我们没有快速处理,会导致该用户一直处于阻塞状态。
当其他用户做同样的请求,也会面临着同样的问题,服务器的资源都是有限的,将整个服务器拖垮都是有可能的。
限流的三种思路
计数器算法
算法比较简单,例如设定接口一分钟之内请求次数不得高于1000次,那么就设定这一分钟内的计数器,判断是否在1000次内,如果高于1000次,那么就拒绝访问。
漏桶算法
强制限制速率的一种做法
令牌桶算法
令牌桶算法的原理是系统会以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务。
二、Sentinel 梗概介绍(摘自官方文档)
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
Sentinel 具有以下特征:
- 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
- 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
- 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
- 完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
三、项目引入Sentinel
1.导入Maven依赖
如果不与第三方进行整合,单单使用Sentinel的核心库,即可
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
<version>1.8.0</version>
</dependency>
如果与Spring cloud alibaba进行整合,则引入starter即可。
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
2.Sentinel 中的控制台
Sentinel 控制台主要负责管理推送规则、监控、集群限流分配管理、机器发现等。在引入Maven依赖后,配置即可,默认端口为8080
百度云下载Sentinel控制台地址
下载完成后,使用java -jar
命令运行即可。
# 服务端口
server.port=8084
spring.cloud.sentinel.transport.dashboard =localhost:8080
# 若8719占用,则从8719开始+1
spring.cloud.sentinel.transport.port=8719
# 注册到Nacos中
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
当我们打开Sentinel控制台,就会发现有应用显示在Sentinel控制台,需要注意的是,这里需要访问访问一次后台接口服务,才能在Sentinel控制台进行控制。
3.Sentinel中的@SentinelResource
@SentinelResource
注解用来标识资源是否被限流、降级,可以加载Service上,也可以加载后台接口Controller上.
如果需要更详细地了解Sentinel注解,可参考Sentinel注解文档
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(ServiceApplication.class, args);
}
}
@Service
public class TestService {
@SentinelResource(value = "sayHello")
public String sayHello(String name) {
return "Hello, " + name;
}
}
@RestController
public class TestController {
@Autowired
private TestService service;
@GetMapping(value = "/hello/{name}")
public String apiHello(@PathVariable String name) {
return service.sayHello(name);
}
}
上述例子上该注解的属性 sayHello 表示资源名。
注:一般推荐将 @SentinelResource 注解加到服务实现上,而在 Web 层直接使用 Spring Cloud Alibaba 自带的 Web 埋点适配。Sentinel Web 适配同样支持配置自定义流控处理逻辑,参考 相关文档。
4.RestTemplate 支持
Spring Cloud Alibaba Sentinel 支持对 RestTemplate 的服务调用使用 Sentinel 进行保护,在构造 RestTemplate bean的时候需要加上 @SentinelRestTemplate 注解。
@Bean
@SentinelRestTemplate(blockHandler = "handleException", blockHandlerClass = ExceptionUtil.class)
public RestTemplate restTemplate() {
return new RestTemplate();
}
@SentinelRestTemplate 注解的属性支持限流(blockHandler, blockHandlerClass)和降级(fallback, fallbackClass)的处理。
其中 blockHandler 或 fallback 属性对应的方法必须是对应 blockHandlerClass 或 fallbackClass 属性中的静态方法。
该方法的参数跟返回值跟 org.springframework.http.client.ClientHttpRequestInterceptor#interceptor 方法一致,其中参数多出了一个 BlockException 参数用于获取 Sentinel 捕获的异常。
比如上述 @SentinelRestTemplate 注解中 ExceptionUtil 的 handleException 属性对应的方法声明如下:
public class ExceptionUtil {
public static ClientHttpResponse handleException(HttpRequest request, byte[] body, ClientHttpRequestExecution execution, BlockException exception) {
...
}
}
应用启动的时候会检查 @SentinelRestTemplate 注解对应的限流或降级方法是否存在,如不存在会抛出异常。
@SentinelRestTemplate 注解的限流(blockHandler, blockHandlerClass)和降级(fallback, fallbackClass)属性不强制填写。
当使用 RestTemplate 调用被 Sentinel 熔断后,会返回 RestTemplate request block by sentinel 信息,或者也可以编写对应的方法自行处理返回信息。这里提供了 SentinelClientHttpResponse 用于构造返回信息。
Sentinel RestTemplate 限流的资源规则提供两种粒度:
httpmethod:schema://host:port/path:协议、主机、端口和路径
httpmethod:schema://host:port:协议、主机和端口
例如以 https://www.taobao.com/test 这个 url 并使用 GET 方法为例。对应的资源名有两种粒度,分别是 GET:https://www.taobao.com 以及 GET:https://www.taobao.com/test
使用Sentinel控制台进行流控、服务降级
在对服务标注@SentinelResource(value = "sayHello")
注解后,就可以使用Sentinel控制台设定流控、降级、热点数据降级规则了。
流控
直接: 例如当QPS达到阈值时,直接拒绝请求
关联:服务A与服务B相关联,当A达到阈值,B则进行流控,也就是拒绝请求
快速失败:达到阈值,直接失败
Warm Up:预热/冷启动模式,有一个概念叫做coldFactor,默认为3,是写死的。当阈值/coldFactor,如下图情况,初始阈值为10/3=3,如果5s持续达到阈值3,则阈值变为10
在源码中表现为,WarmupController中的构造函数,写死为3
排队等待:思想为漏桶算法,把请求按照设置的间隔处理。
降级
除了流量控制以外,对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一。一个服务常常会调用别的模块,可能是另外的一个远程服务、数据库,或者第三方 API 等。
现代微服务架构都是分布式的,由非常多的服务组成。不同服务之间相互调用,组成复杂的调用链路。以上的问题在链路调用中会产生放大的效果。复杂链路上的某一环不稳定,就可能会层层级联,最终导致整个链路都不可用。因此我们需要对不稳定的弱依赖服务调用进行熔断降级,暂时切断不稳定调用,避免局部不稳定因素导致整体的雪崩。熔断降级作为保护自身的手段,通常在客户端(调用端)进行配置。
降级策略主要有三种
慢调用比例 (SLOW_REQUEST_RATIO) 选择以慢调用比例作为阈值,需要设置允许的慢调用 RT(即最大的响应时间),请求的响应时间大于该值则统计为慢调用。当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且慢调用的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则会再次被熔断。
异常比例 (ERROR_RATIO): 当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。异常比率的阈值范围是 [0.0, 1.0],代表 0% - 100%。
异常数 (ERROR_COUNT): 当单位统计时长内的异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。
热点数据降级
何为热点?热点即经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的 Top K 数据,并对其访问进行限制。比如:
商品 ID 为参数,统计一段时间内最常购买的商品 ID 并进行限制
用户 ID 为参数,针对一段时间内频繁访问的用户 ID 进行限制
热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。
按上图的配置,当传入的第一个参数(索引位置为0)QPS达到阈值1,那么就会降级,并在一秒后恢复, 如果不传入参数,那么就不会触发这个热点数据保护,因为这个热点参数保护是基于参数说的。
@GetMapping(value = "/testHotKey")
@SentinelResource(value = "testHotKey",blockHandler = "deal_hot_key")
public String testHotKey(@RequestParam(value = "p1",required = false) String p1,
@RequestParam(value = "p2",required = false) String p2) {
return "Hello Sentinel Hot Key";
}
// 触发保护策略处理方法
public String deal_hot_key(String p1, String p2, BlockException exception)
{
return "deal_hot_key";
}
当慢速正常访问时,可以正常访问
但当,带着p1参数,请求次数QPS大于阈值1时,则会触发保护策略。
参考文章
Sentinel官方文档
Spring cloud Alibaba 从入门到放弃
最后
以上就是想人陪大炮为你收集整理的SpringCloud Alibaba | Sentinel 流控与服务降级的全部内容,希望文章能够帮你解决SpringCloud Alibaba | Sentinel 流控与服务降级所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复