Hystrix断路器
分布式面临的问题
复杂分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系再某些时候将不可避免的失败。
服务雪崩
多个微服务之间调用的时候,假设服务A调用服务B和**服务C,**服务B和服务C又调用其他的服务,这就是所谓的“扇出”。如果扇出的链路上某个服务的调用响应时间过长或者不可用,对服务A的调用就会占用越来越多的系统资源,进而引起系统崩溃,造成“雪崩效应”。
对于高流量的应用来说,单一的后端依赖可能会导致所有服务器上的所有资源都在几秒内饱和。比失败更糟糕的是,这些应用程序还可能导致服务之间调用的延迟增加,备份队列,线程和其他系统资源紧张,导致整个系统发生更多的级联故障。这些都表示需要对故障和延迟队列进行隔离和管理,以便单个依赖关系的失败,不能取消整个应用程序或系统。所以,通常当发现一个模块下的某个实例失败后,这时候这个模块还会接受流量,然后这个有问题的模块还调用了其他的模块,这样就会发生级联故障或者雪崩。
Hysrtix
Hystrix是一个用于处理分布式系统的延迟和容错开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等等。Hystrix能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。
“断路器”本身是一种开关装置,当某个服务单元发生故障后,通过断路器的故障监控(类似熔断保险丝),向调用方向返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布式系统中的蔓延,最后雪崩。
Hysrtix 的作用又服务降级、服务熔断、以及接近实时的监控。
重要概念
服务降级
降级是从系统功能优先级的角度考虑如何应对系统故障。服务降级是当服务器压力剧增的情况下,根据当前业务情况及流量对一些服务和页面有策略的降级,以此释放服务器资源以保证核心任务的正常运行。
服务降级的方式
- 延迟服务: 比如发表了评论,重要服务,比如在文章中显示正常,但是延迟给用户增加积分,只是放到一个缓存中,等服务平稳之后再执行。
- 在粒度范围内关闭服务(片段降级或服务功能降级): 比如关闭相关文章的推荐,直接关闭推荐区。
- 页面异步请求降级: 比如商品详情页上有推荐信息/配送至等异步加载的请求,如果这些信息响应慢或者后端服务有问题,可以进行降级。
- 页面跳转(页面降级): 比如可以有相关文章推荐,但是更多的页面则直接跳转到某一个地址。
- 写降级: 比如秒杀抢购,我们可以只进行Cache的更新,然后异步同步扣减库存到DB,保证最终一致性即可,此时可以将DB降级为Cache。
- 读降级: 比如多级缓存模式,如果后端服务有问题,可以降级为只读缓存,这种方式适用于对读一致性要求不高的场景。
服务降级的分类
- 自动开关降级(超时、失败次数、故障、限流)
- 人工开关降级(秒杀、电商大促等)
自动降级分类又分为:
超时降级:主要配置好超时时间和超时重试次数和机制,并使用异步机制探测回复情况
失败次数降级:主要是一些不稳定的api,当失败调用次数达到一定阀值自动降级,同样要使用异步机制探测回复情况
故障降级:比如要调用的远程服务挂掉了(网络故障、DNS故障、http服务返回错误的状态码、rpc服务抛出异常),则可以直接降级。降级后的处理方案有:默认值(比如库存服务挂了,返回默认现货)、兜底数据(比如广告挂了,返回提前准备好的一些静态页面)、缓存(之前暂存的一些缓存数据)
限流降级:当我们去秒杀或者抢购一些限购商品时,此时可能会因为访问量太大而导致系统崩溃,此时开发者会使用限流来进行限制访问量,当达到限流阀值,后续请求会被降级:降级后的处理方案可以是:排队页面(将用户导流到排队页面等一会重试)、无货(直接告知用户没货了)、错误页(如活动太火爆了,稍后重试)
服务熔断
熔断是应对微服务雪崩效应的一种链路保护机制,类似股市、保险丝。服务熔断是应对雪崩效应的一种微服务链路保护机制。例如在高压电路中,如果某个地方的电压过高,熔断器就会熔断,对电路进行保护。同样,在微服务架构中,熔断机制也是起着类似的作用。当调用链路的某个微服务不可用或者响应时间太长时,会进行服务熔断,不再有该节点微服务的调用,快速返回错误的响应信息。当检测到该节点微服务调用响应正常后,恢复调用链路。
降级和熔断的区别
熔断和降级是两个比较容易混淆的概念,两者的含义并不相同。
*降级的目的在于应对系统自身的故障,而熔断的目的在于应对当前系统依赖的外部系统或者第三方系统的故障。*
常见的熔断器组件
- Hystrix
- Resilience4J
- Sentinel
- SpringRetry
服务限流
限流,是指在使用缓存和降级无效的场景。比如当达到阈值后限制接口调用频率,访问次数,库存个数等,在出现服务不可用之前,提前把服务降级。只服务好一部分用户。