文章目录
三、断路器-Hystrix
在分布式环境中,许多服务依赖项不可避免地会失败。Hystrix是一个库,它通过添加延迟容忍和容错逻辑来帮助您控制这些分布式服务之间的交互。Hystrix通过隔离服务之间的访问点、停止它们之间的级联故障以及提供后备选项来实现这一点,所有这些都可以提高系统的整体弹性。
Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统中,许多依赖不可避免的会调用失败,超时、异常等,Hystrix能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障(服务雪崩现象),提高分布式系统的弹性。
3.1、相关概念
3.1.1、服务雪崩
在微服务架构中通常会有多个服务层调用,基础服务的故障可能会导致级联故障,进而造成整个系统不可用的情况,这种现象被称为服务雪崩效应。服务雪崩效应是一种因“服务提供者”的不可用导致“服务消费者”的不可用,并将不可用逐渐放大的过程
如果下图所示:A作为服务提供者,B为A的服务消费者,C和D是B的服务消费者。A不可用引起了B的不可用,并将不可用像滚雪球一样放大到C和D时,雪崩效应就形成了。
# 引起雪崩的原因:
1、硬件故障;
2、程序Bug;
3、缓存击穿(用户大量访问缓存中没有的键值,导致大量请求查询数据库,使数据库压力过大);
4、用户大量请求;
# 三个阶段
第一阶段: 服务不可用;
第二阶段:调用端重试加大流量(用户重试/代码逻辑重试)
第三阶段:服务调用者不可用(同步等待造成的资源耗尽)
# 解决方案
(1)、应用扩容(扩大服务器承受力)
(2)、流量控制(超出限定流量,返回类似重试页面让用户稍后再试)
(3)、缓存:将用户可能访问的数据大量的放入缓存中,减少访问数据库的请求
(4)、服务降级
服务接口拒绝服务
页面拒绝服务
延迟持久化
随机拒绝服务
(5)、服务熔断
2.1.2、服务熔断
“熔断器”本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控,某个异常条件被触发,直接熔断整个服务。向调用方法返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方法无法处理的异常,就保证了服务调用方的线程不会被长时间占用,避免故障在分布式系统中蔓延,乃至雪崩。如果目标服务情况好转则恢复调用。服务熔断是解决服务雪崩的重要手段。
2.1.3、服务降级
服务压力剧增的时候根据当前的业务情况及流量对一些服务和页面有策略的降级,以此环节服务器的压力,以保证核心任务的进行。同时保证部分甚至大部分任务客户能得到正确的相应。也就是当前的请求处理不了了或者出错了,给一个默认的返回。
2.1.4、降级和熔断的总结
# 1.共同点
- 目的很一致,都是从可用性可靠性着想,为防止系统的整体缓慢甚至崩溃,采用的技术手段;
- 最终表现类似,对于两者来说,最终让用户体验到的是某些功能暂时不可达或不可用;
- 粒度一般都是服务级别,当然,业界也有不少更细粒度的做法,比如做到数据持久层(允许查询,不允许增删改);
- 自治性要求很高,熔断模式一般都是服务基于策略的自动触发,降级虽说可人工干预,但在微服务架构下,完全靠人显然不可能,开关预置、配置中心都是必要手段;
# 2.异同点
- 触发原因不太一样,服务熔断一般是某个服务(下游服务)故障引起,而服务降级一般是从整体负荷考虑;
- 管理目标的层次不太一样,熔断其实是一个框架级的处理,每个微服务都需要(无层级之分),而降级一般需要对业务有层级之分(比如降级一般是从最外围服务开始)
# 3.总结
- 熔断必会触发降级,所以熔断也是降级一种,区别在于熔断是对调用链路的保护,而降级是对系统过载的一种保护处理
3.2、服务降级
当较低级别的服务中的服务故障可能会导致级联故障,直至用户。甚至出现雪崩现象,如果使用了Hystrix则可触发熔断来防止级联故障,那么断路器的触发条件是什么呢?
A service failure in the lower level of services can cause cascading failure all the way up to the user. When calls to a particular service exceed circuitBreaker.requestVolumeThreshold
(default: 20 requests) and the failure percentage is greater than circuitBreaker.errorThresholdPercentage
(default: >50%) in a rolling window defined by metrics.rollingStats.timeInMilliseconds
(default: 10 seconds), the circuit opens and the call is not made. In cases of error and an open circuit, a fallback can be provided by the developer.(摘自springcloud hystrix官网 https://cloud.spring.io/spring-cloud-netflix/2.2.x/reference/html/#hystrix-metrics-stream)
译文:较低级别的服务中的服务故障可能会导致级联故障,直至用户。当在由(默认值:10秒)定义的滚动窗口中,对特定服务的调用超过circuitBreaker.requestVolumeThreshold
(默认值:20个请求)并且失败百分比大于circuitBreaker.errorThresholdPercentage
(默认值:> 50%)时metrics.rollingStats.timeInMilliseconds
,电路将断开并且不会进行调用。在错误和断路的情况下,开发人员可以提供后备功能。
# 总结 断路器的触发条件
1、当满足一定的阀值的时候(默认10秒内超过20个请求次数)
2、 当失败率达到一定的时候(默认10秒内超过50%的请求失败)
3、 到达以上阀值,断路器将会开启
4、 当断路器开启的时候,所有请求都不会进行转发
5、 一段时间之后(默认是5秒),这个时候断路器是半开状态,会让其中一个请求进行转发。如果成功,断路器会关闭,若失败,继续开启。重复4和5。
在清楚断路器的触发条件的时候我们来模拟服务熔断,并使用hystrix来进行处理
-
引入hystrix依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>
-
为了方便演示,新建两个项目。订单服务对外暴露的接口如下。在商品服务中新增方法,这里选择抛出异常的方式来触发服务熔断。
package com.laodai.controller; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.Map