微服务架构(5)——熔断降级 - Go语言中文社区

微服务架构(5)——熔断降级


目录:

1、为什么需要熔断降级
2、熔断降级框架对比选型
3、集成Sentinel
4、Sentinel原理

为什么需要熔断降级

在微服务化的系统中会存在一个比较严重的问题,叫做服务雪崩。服务雪崩是怎么发生的呢?
下单
如上图,假设一个用户进行一个下单操作,商品服务需要调用订单服务添加订单数据,下单成功后,订单服务又需要调用积分服务给下单成功的用户增加一些积分。
要是有一天,积分服务突然挂了。这时一个下单请求过来的话,在订单服务调用积分服务时,因为积分服务挂了。请求一直卡在这里,等到过了设置的超时时间,才返回请求超时的错误,去释放这个连接。
如果之前的请求没有超时,又不断有新的请求进来,新请求又继续卡在这里等待超时,那么请求在订单服务就会堆积的越来越多,导致订单服务线程资源耗尽。
这时商品服务去调用订单服务的请求就会阻塞、等待、超时。导致商品服务请求堆积,商品服务又变的不可用。
这就导致了服务雪崩。

为了解决这个问题,那么就需要对异常的服务进行熔断,防止影响其它的服务。
在下单的这个调用链中,其实积分服务不是必须的。积分没有加上其实影响也不大,要是有用户进行投诉反馈,那么我们手工给他加上就可以。所以积分服务发生异常,我们及时熔断就可以,避免影响其它服务。只要有请求是去调用积分服务的,直接返回调用失败,不需要等到超时时间再返回。

降级就是说,订单服务发现积分服务有明显的延迟或是不可用,那么就不去调用积分服务了,直接走本地降级策略。比如说直接打印一条日志“XX用户下单成功,增加10积分”。后续再通过人工的方式把积分加上。这样的话就没有影响到整个系统的可用性,用户还是可以正常下单。

熔断降级框架对比选型

当下我们用的比较多的熔断降级框架主要就是Sentinel和Hystrix,下面就基于这两种框架来做一个对比。

熔断降级策略

Sentinel 与 Hystrix 都支持基于失败比率(异常比率)的熔断降级,在调用达到一定量级并且失败比率达到设定的阈值时自动进行熔断,此时所有对该资源的调用都会直接被拒绝,直到过了指定的时间窗口后才启发性地恢复。
Sentinel 还支持基于平均响应时间的熔断降级,可以在服务响应时间持续飙高的时候自动熔断,拒绝掉更多的请求,直到一段时间后才恢复。这样可以防止调用非常慢造成级联阻塞的情况。

隔离策略

Hystrix 提供两种隔离策略:线程池隔离和信号量隔离。
线程池隔离: 在上面分析服务雪崩的时候我们了解到,要是积分服务挂了,那么订单服务调用积分服务的请求就会阻塞,导致线程资源用完。这里线程池隔离就是说,假如订单服务有200个线程资源,那么创建一个线程池,为这个线程池分配20个线程资源。这20个线程就是专门用来调用积分服务的,假如积分服务挂了,阻塞也是只阻塞这20个线程,订单服务还有剩余的180个线程资源可以使用,就不会导致订单服务处于不可用的状态了。
线程池隔离策略隔离度比较高,可以针对某个资源的线程池去进行处理而不影响其它资源。缺点就是线程上下文切换比较频繁,对性能影响比较大。
信号量隔离:信号量隔离就是限制调用的并发数,比如说当前有20个请求在调用积分服务了,第21个请求过来去调用积分服务的时候就直接拒绝。
信号量隔离策略优点就是减少了线程上下文切换带来的消耗,缺点是无法对慢调用自动进行降级,只能等待客户端自己超时,因此仍然可能会出现级联阻塞的情况。

Sentinel使用的额隔离策略是信号量隔离,但是它可以结合基于响应时间的熔断降级模式,可以在不稳定资源的平均响应时间比较高的时候自动降级,防止过多的慢调用占满并发数,影响整个系统。

集成Sentinel

1 部署Sentinel-dashboard

我这边是通过docker来进行部署的。
首先拉取sentinel镜像,命令如下

docker pull bladex/sentinel-dashboard

创建容器,部署sentinel。命令如下:

docker run --name sentinel -d  -p 8858:8858  bladex/sentinel-dashboard

运行成功后,通过docker ps 命令可以看到sentinel 已经处于运行状态了。
在这里插入图片描述
然后我们在浏览器上访问 127.0.0.1:8858,就能进入到sentinel 的控制台了。账号和密码都是 sentinel。

在这里插入图片描述

2 项目中集成Sentinel

在dubboclient添加依赖sentinel依赖

<!-- sentinel -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency> 

在dubboclient中添加sentinel配置

spring.cloud.sentinel.transport.dashboard = 127.0.0.1:8858
spring.cloud.sentinel.transport.port = 8719
management.endpoints.web.exposure.include = '*'

在需要进行熔断降级的方法上添加@SentinelResource(value = “pay”)注解。
在这里插入图片描述
然后我们访问/pay这个路径后,在控制台就能看到监控信息了。
在这里插入图片描述
在控制台我们可以配置熔断降级的规则。
在这里插入图片描述
这里资源名称要与我们@SentinelResource注解中value的值一致。
上图配置就是表明,调用pay这个资源的时候,如果异常请求(响应时间大于500ms)数量大于5个,并且异常请求比例大于0.1,那么就会触发熔断,熔断时间为10s。
当然还有其他配置规则的方式,具体可以参考sentinel配置sentinel官方文档

Sentinel原理

前面已经说过Sentinel是基于信号量来做隔离策略的,就一上面配置的规则为例。
响应时间:500ms
最小请求数:5
异常比例:0.1
熔断时间:10
当一个请求过来访问pay这个资源的时候,这时就会记录pay的总请求数+1。
如果这个请求正常通过了,那么通过的请求数+1。
如果请求超过了响应时间500ms,那么就是异常请求,异常请求数就+1。
这时再来一个请求,要是发现此时异常请求的数量已经有5个了,并且异常请求的数量/总请求数量大于了0.1,那么这个请求就会被拒绝,并且在接下来的10s内,进来访问pay资源的请求都会被拒绝。

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/tack_back/article/details/111341852
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2023-01-03 21:37:02
  • 阅读 ( 287 )
  • 分类:架构

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢