SpringCloud | 第七章: Hystrix 服务容错机制

版权声明:喜欢的点个赞吧!欢迎转载,请注明出处来源,博文地址: https://blog.csdn.net/u012294515/article/details/88184097

前言

至此,前几章节内容已用 Eureka 实现了注册与发现,Ribbon 实现了客户端负载均衡,Fegin 实现了声明式的API调用。
在微服务架构中,一个服务可能会调用很多的其他微服务应用,虽然做了多集群部署,但可能还会存在诸如网络原因或者服务提供者自身处理的原因,或多或少都会出现请求失败或者请求延迟问题,若服务提供者长期未对请求做出回应,服务消费者又不断的请求下,可能就会造成服务提供者服务崩溃,进而服务消费者也一起跟着不可用,严重的时候就发生了系统雪崩了。因此服务容错机制就显得尤为重要。本章节,学习如何利用 Hystrix 进行服务容错。

知识预热

关于容错

容错处理是指软件运行时,能对由非正常因素引起的运行错误给出适当的处理或信息提示,使软件运行正常结束 --百度百科

从百度百科的解释中可以看出,简单理解,所谓的容错处理其实就是捕获异常了,不让异常影响系统的正常运行,正如java中的try catch一样。

而在微服务调用中,自身异常可自行处理外,对于依赖的服务若发生错误,或者调用异常,或者调用时间过长等原因时,避免长时间等待,造成系统资源耗尽。
一般上都会通过设置请求的超时时间,如http请求中的ConnectTimeoutReadTimeout;再或者就是使用熔断器模式,隔离问题服务,防止级联错误等。

雪崩效应

在微服务架构中,存在很多的微服务单元,各个微服务之间通过网络进行通讯,难免出现依赖关系,若某一个单元出现故障,就很容易因依赖关系而引发故障的蔓延,产生“雪崩效应”,最终导致整个系统的瘫痪。

如果下图所示:A作为服务提供者,B为A的服务消费者,C和D是B的服务消费者。A不可用引起了B的不可用,并将不可用像滚雪球一样放大到C和D时,雪崩效应就形成了。
在这里插入图片描述

熔断器

熔断器,和现实生活中的空气开关作用很像。它可以实现快速失败,如果它在一段时间内侦测到许多类似的错误,会强迫其以后的多个调用快速失败,不再访问远程服务器,从而防止应用程序不断地尝试执行可能会失败的操作,使得应用程序继续执行而不用等待修正错误,或者浪费CPU时间去等到长时间的超时产生。熔断器也可以使应用程序能够诊断错误是否已经修正,如果已经修正,应用程序会再次尝试调用操作

熔断器模式就像是那些容易导致错误的操作的一种代理。这种代理能够记录最近调用发生错误的次数,然后决定使用允许操作继续,或者立即返回错误。
在这里插入图片描述
简单讲解下上图的逻辑转换:

  • 正常情况下,断路器关闭,可正常请求依赖的服务。
  • 当一段时间内,请求失败率达到一定阈值(例如你设置了50次,或者错误率50%,或100次/分钟),断路器就会打开,在该状态下,对应用程序的请求会立即返回错误响应,而不调用后端的服务。有些时候,我们可以 cache 住上次成功请求,直接返回缓存(当然,这个缓存放在本地内存就好了),如果没有缓存再返回错误(缓存的机制最好用在全站一样的数据,而不是用在不同的用户间不同的数据,因为后者需要缓存的数据有可能会很多)。
  • 断路器打开一段时间后,会自动进入半开状态。此时,断路器可以允许应用程序一定数量的请求去调用服务。如果这些请求对服务的调用成功,那么可以认为之前导致调用失败的错误已经修正,此时熔断器切换到闭合状态 (并且将错误计数器重置)。

因此,我们可以通过以上机制保护应用,从而防止雪崩效应并提升应用的可用性。

Hystrix简介

Hystrix是一个实现了超时机制和断路器模式的工具类库,用于隔离访问远程系统、服务或者第三方库,防止级联失败,从而提升系统的可用性与容错性。

Hystrix 主要通过以下几点实现延迟和容错:

  • 包裹请求:使用HystrixCommand包裹对依赖的调用逻辑,每个命令在独立线程中执行,这是用到了设计模式“命令模式”。
  • 跳闸机制:当某服务的错误率超过一定阈值时,Hystrix可以自动或手动跳闸,停止请求该服务一段时间。
  • 资源隔离:Hystrix为每个依赖都维护了一个小型的线程池,如果该线程池已满,发往该依赖的请求就被立即拒绝,而不是排队等候,从而加速判定失败。
  • 监控:Hystrix可以近乎实时的监控运行指标和配置的变化。如成功、失败、超时、被拒绝的请求等。
  • 回退机制:当请求失败、超时、被拒绝,或当断路器打开时,执行回退逻辑。回退逻辑可自定义。
  • 自我修复:断路器打开一段时间后,会自动进入半开状态,断路器打开、关闭、半开的逻辑转换。

快速实现 Feign + Hystrix

因为熔断只是作用在服务调用这一端,因此我们根据上一篇的示例代码只需要改动spring-cloud-fegin项目相关代码就可以。因为,Feign中已经依赖了Hystrix所以在maven配置上不用做任何改动。

  1. 修改配置文件application.yml,开启Fegin hystrix
feign:
  hystrix:
    enabled: true
  1. 创建回调类
    创建HelloRemoteHystrix类继承与HelloRemote实现回调的方法
@Component
public class HelloRemoteHystrix implements HelloRemote {
    @Override
    public String msg(String name) {
        return "hello!" +name+", 触发熔断了~ ";
    }
}
  1. 添加fallback属性。在HelloRemote类添加指定fallback类,在服务熔断的时候返回fallback类中的内容。
@FeignClient(name = "client",fallback = HelloRemoteHystrix.class)
@Component
public interface HelloRemote {
    @GetMapping("/msg")
    public String msg(@RequestParam("name")String name);
}
  1. 依次启动ResgitryClientFegin三个项目。

    浏览器中输入:http://localhost:7001/hello?name=xyua

    返回:hello~ xyua! welcome spring cloud.8081

    说明加入熔断相关信息后,不影响正常的访问。接下来我们手动停止Client项目再次测试:

    浏览器中输入:http://localhost:7001/hello?name=xyua

    返回:hello!xyua, 触发熔断了~

    根据返回结果说明熔断成功。

小结

本章根据前几篇的代码,将 Hystrix 和 Fegin结合,简单的演示了服务不可访问时的熔断机制。后续有时间再详细介绍Hystrix的其他特性。

参考

  1. 《Spring + Cloud 与 Docker 微服务架构实战 》一书
  2. 服务容错保护(Hystrix)
  3. 熔断器Hystrix
  4. 弹力设计篇之“熔断设计”

猜你喜欢

转载自blog.csdn.net/u012294515/article/details/88184097