Hystrix
雪崩效应
微服务架构中,少不了各个微服务之间的调用。服务调用之间会有依赖关系。微服务A调用微服务B,微服务B调用微服务C之后才能完成整个返回结果,完成整个请求链路。
扇入:该服务被其他服务调用的次数。(该模块复用性好)
扇出:该服务调用其他的服务的个数。(该模块业务复杂)
所谓雪崩效应如果扇出的链路上某个微服务的调用时间过长或者不可用,对调用方微服务来说就会占用越来越多的系统资源,进而引起系统崩溃。
解决方案
服务熔断
当扇出的链路上某个服务不可用或者响应时间过长,熔断该节点的服务调用,进行服务降级,快速返回错误信息。当检测的该节点恢复后,重新发起调用。
- 断:切断对下游服务的调用。
- 服务降级和服务熔断往往一起使用。
服务降级
整体资源不够用了,先关停一些不关紧的服务。
当服务出问题或者影响到核⼼流程的性能时,暂时将服务屏蔽掉,待⾼峰或者问题解决后再打开 。
服务限流
在系统流量过大时,通过多种策略限制请求,以免造成系统崩溃。
Hystrix 简介
是一种容错机制,用于隔离访问远程系统、服务或者第三方库,防止级联失败,从而提高系统的可用性与容错性。
线程池隔离机制
流程:当请求来时,hystrix分配一个线程去处理该请求。
默认Hystrix 有一个线程池(10个),为所有添加了@hystrixCommond方法提供线程。如果这些方法接收请求的个数超过10个,其他请求就会等待。
场景: 现在有两个方法1,2,方法1,2 公共10个线程,方法1 要去扇出的中微服务A,方法2要调用扇出的微服务B。
假如方法1 接收了10个请求,耗尽了hystrix提供的线程池的线程。此时如果请求到达方法2 ,方法2没有线程可用,导致无法调用服务B,而不是服务B本身不可用。
改善:
为了避免问题服务请求过多导致正常服务⽆法访问, Hystrix 不是采⽤增加线程数,⽽是单独的为每⼀个控制⽅法创建⼀个线程池的⽅式,这种模式叫做“舱壁模式",也是线程隔离的⼿段。
可通过配置修改线程池的参数(线程数、等待队列等等)
工作流程
当请求到达时,hystrix会从线程中去除线程处理请求。当调用远程服务出现错误时:
- 当调用出现问题时,会开启一个时间窗口(10s)
- 在整个窗口期,首先判断请求是否达到最小请求数。如果没有达到,则重置统计信息。重新发起调用。
- 如果达到最小请求数,会查看错误数量是否达到阙值(失败的请求数占所有请求的百分比)。如果没有,回到第一步。如果达到,就跳闸。(不再请求对应服务)
- 如果发生跳闸,就会发生开启一个活动窗口(默认5s)——每隔5s,Hystrix会让一个请求通过,到达那个问题服务。
- 如果调用通过,重置断路器,回到第一步。
- 如果失败,回到图中跳闸的位置。
@HystrixCommand(
// 线程池标识,要保持唯一,不唯一的话就共用了
threadPoolKey = "findResumeOpenStateTimeoutFallback",
// 线程池细节属性配置
threadPoolProperties = {
@HystrixProperty(name="coreSize",value = "2"), // 线程数
@HystrixProperty(name="maxQueueSize",value="20") // 等待队列长度
},
// commandProperties熔断的一些细节属性配置
commandProperties = {
// 每一个属性都是一个HystrixProperty
@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="2000")
// hystrix高级配置,定制工作过程细节
,
// 统计时间窗口定义
@HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds",value = "8000"),
// 统计时间窗口内的最小请求数
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "2"),
// 统计时间窗口内的错误数量百分比阈值
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "50"),
// 自我修复时的活动窗口长度
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "3000")
}