Hystrix源码解析--HystrixCircuitBreaker--思想层面(一)

一、什么是HystrixCircuitBreaker?

HystrixCircuitBreaker可以防止应用程序重复的尝试调用容易失败的依赖服务。HystrixCircuitBreaker的目的和Retry模式的目的是不同的。Retry模式令应用程序不断的去重试调用依赖服务,直到最后成功。而HystrixCircuitBreaker是阻止应用程序继续尝试无意义的请求。HystrixCircuitBreaker可以按照如下的状态来实现:

  • 关闭:应用程序的请求已经路由到了这个操作。HystrixCircuitBreaker应该维护最近一段时间的错误信息,如果调用操作失败,那么大力增加这个错误信息的数量。如果这个错误数量超过给定时间的阈值,HystrixCircuitBreaker进入到打开状态。这个时候,HystrixCircuitBreaker启动一个超时的Timer,当Timer过期了,代理则进入半开状态。超时Timer的目的是为了给依赖服务一段时间来自我修复之前碰到的问题。
  • 打开:令可能失败的外部调用操作立刻失败,所有的外部调用直接抛异常给应用程序。
  • 半开:只有一定数量的应用请求可以进行操作的调用。如果这些请求成功了,那么就假定之前发生的错误已经被依赖服务自动修复了,而HystrixCircuitBreaker转换成关闭状态,同时重置错误计数器。如果任何请求失败了,那么HystrixCircuitBreaker会假定错误仍然在存在,HystrixCircuitBreaker会重新转换成打开状态,并重启超时Timer给依赖服务更多的时间来自我修复错误。 

二、解决方法

HystrixCircuitBreaker可以防止应用程序不断地尝试执行可能会失败的操作,使得应用程序继续执行而不用等待修正错误,或者浪费CPU时间去等到长时间的超时产生。HystrixCircuitBreaker也可以使应用程序能够诊断错误是否已经修正,如果已经修正,应用程序会再次尝试调用操作。HystrixCircuitBreaker就像是那些容易导致错误的操作的一种代理。这种代理能够记录最近调用发生错误的次数,然后决定是否允许操作继续,或者立即返回错误。

HystrixCircuitBreaker可以使用状态机来实现,内部模拟以下几种状态。

  • 闭合(closed)状态: 对应用程序的请求能够直接引起方法的调用。代理类维护了最近调用失败的次数,如果某次调用失败,则使失败次数加1。如果最近失败次数超过了在给定时间内允许失败的阈值,则代理类切换到断开(Open)状态。此时代理开启了一个超时时钟,当该时钟超过了该时间,则切换到半断开(Half-Open)状态。该超时时间的设定是给了依赖服务恢复正常。
  • 断开(Open)状态:在该状态下,对依赖服务的请求会立即返回错误响应。
  • 半断开(Half-Open)状态:允许对应用程序的一定数量的请求可以去调用依赖服务。如果这些请求对依赖服务的调用成功,那么可以认为之前导致调用失败的错误已经修正,此时Circuit-Breaker切换到闭合状态,并且将错误计数器重置;如果这一定数量的请求有调用失败的情况,则认为导致之前调用失败的问题仍然存在,Circuit-Breaker切回到断开方式,然后开始重置计时器来给依赖服务一定的时间来修正错误。半断开状态能够有效防止正在恢复中的依赖服务被突然而来的大量请求再次拖垮。

各个状态之间的转换如下图:

在Close状态下,错误计数器是基于时间的。在特定的时间间隔内会自动重置。这能够防止由于某次的偶然错误导致熔断器进入断开状态。触发熔断器进入断开状态的失败阈值只有在特定的时间间隔内,错误次数达到指定错误次数的阈值才会产生。在Half-Open状态中使用的连续成功次数计数器记录调用的成功次数。当连续调用成功次数达到某个指定值时,切换到闭合状态,如果某次调用失败,立即切换到断开状态,连续成功调用次数计时器在下次进入半断开状态时归零。

实现熔断器模式使得系统更加稳定和有弹性,在系统从错误中恢复的时候提供稳定性,并且减少了错误对系统性能的影响。它通过快速的拒绝那些试图有可能调用会导致错误的服务,而不会去等待操作超时或者永远不会不返回结果来提高系统的响应事件。如果熔断器设计模式在每次状态切换的时候会发出一个事件,这种信息可以用来监控服务的运行状态,能够通知管理员在熔断器切换到断开状态时进行处理。

可以对熔断器模式进行定制以适应一些可能会导致远程服务失败的特定场景。比如,可以在熔断器中对超时时间使用不断增长的策略。在熔断器开始进入断开状态的时候,可以设置超时时间为几秒钟,然后如果错误没有被解决,然后将该超时时间设置为几分钟,依次类推。在一些情况下,在断开状态下我们可以返回一些错误的默认值,而不是抛出异常。

猜你喜欢

转载自blog.csdn.net/pfnie/article/details/81988404
今日推荐