如果服务提供者响应非常缓慢,那么消费者对提供者的请求就会被强制等待,直接提供者响应或超时。在高负载场景下,如果不做任何处理,此类问题可能会导致服务消费者的资源耗竭甚至整个系统的崩溃。这时,就需要进行容错处理
雪崩效应:
”基础服务故障“导致”级联故障“的现象称为雪崩效应。雪崩效应描述的是提供者不可用导致消费者不可能,并将不可用逐渐放大的过程。
如图,A作为服务提供者,B为A的服务消费者,C和D是B的服务消费者。当A不可用引起了B的不可用,并将不可用像滚雪球一样放大到C和D时,雪崩效应就 形成了。
如何容错:
为网络请求设置超时
正常情况下,一个远程调用一般在几十毫秒内就能得到响应了。如果依赖的服务不可用或网络有问题,那么响应时间就会变得很长
通常情况下,一次远程调用对应着一个线程/进程。如果相应太慢,这个线程/进程就得不到释放。而线程有对应着系统资源,如果得不到释放的线程越积越多,资源就会逐渐被耗尽,最终导致服务的不可用
使用断路器模式
如果对某个微服务的请求有大量超时,再去让新的请求访问该服务已经没有任何意义,只会消耗资源。
断路器可理解为对容易导致错误的操作的代理。这种代理能统计一段时间内调用失败的次数,并决定是正常请求依赖的服务还是直接返回
断路器状态转换图:
正常情况下,断路器关闭,可正常请求依赖的服务
当一段时间内,请求失败率达到一定阀值,断路器就会打开,同时不会再去请求依赖的服务
断路器打开一段时间后,会自动进入半开状态。此时断路器可允许一个请求访问依赖的服务。如果该请求能够调用成功,则关闭断路器;否则继续保持打开状态
HsysTrix实现容错:
Hystrix时由Netflix开源的一个延迟和容错库,用于隔离访问远程系统、服务或第三方库,防止级联失败,从而提升系统的可用性与容错性。Hystrix主要通过以下几点实现延迟和容错
包裹请求:使用HystrixCommand(或HystrixObservableCommand)包裹对依赖的调用逻辑,每个命令在单独线程中执行。(命令模式)
跳闸机制:当某服务的错误率超过一定阀值时,Hystrix可以自动或手动跳闸,停止请求该服务一段时间
资源隔离:Hystrix为每个依赖都维护了一个小型的线程池。如果该线程池已满,发往该依赖的请求就被立即拒绝,而不是排队等候,从而加速失败判定
监控:Hystrix可以近乎实时地监控运行指标和配置的变化,例如成功、失败、超时以及被拒绝的请求等
回退机制:当请求失败、超时、被拒绝或断路器打开时,执行回退逻辑。回退逻辑由开发人员自行提供
自我修复:断路器打开一段事件后,会自动进入”半开“状态。
Hystrix断路器状态监控:
访问http://localhost:8080/health 获得Hystrix状态
如果执行了回退逻辑,但Hystrix的状态依然是UP,是因为失败率还没有达到阀值(默认5秒内20次失败)
execution.isolation.strategy指定隔离策略
Hystrix隔离策略:
THREAD(线程隔离):HystrixCommand将会在单独的线程上执行,并发请求受线程池中的线程数量的限制
SEMAPHORE(信号量隔离):HystrixCommand将会在调用线程上执行,开销相对较小,并发请求接受到信号量个数的限制
Hystrix默认并推荐使用线程隔离,因为这种方式有一个除网络超时以外的额外保护层。
一般来说,只有当调用负载非常高时才会需要使用信号量隔离,因为这种场景下使用THREAD开销会比较高。信号量隔离一半仅适用于非网络调用的隔离
如果发生找不到上下文的运行时异常,可以将隔离策略设置为SEMAPHORE,如使用注解@HystrixCommand(fallbackMethod = "testService", commandPropperties = {@HystrixProperty(name = "execution.isolation.strategy", value = "SEMAPHORE")})
05-26 14:08