为什么需要熔断
熔断这个词一听从生活中就是保险丝超过一定的温度后自动断开,以此来保护家用电器,属于电路中自我保护装置。如果没有熔断,那么家用电器一定会损坏的。
进一步再来分析一下,在分布式系统中,各个系统之间其实会经常出现故障问题,如果能够自动检测到下游系统故障之后,直接断开请求,可以很好的保护系统。
那么重试和熔断的区别是什么,重试是在一定的时间内,系统可以恢复后进行重试,如果超过一定时间没有恢复,那么就需要熔断设计。
熔断设计
熔断设计可以保证频繁的调用下游系统而一直返回错误,造成CPU的资源浪费以及长时间的超时等待,二是可以保证在下游系统恢复之后,可以切换到系统正常调用状态。所以这么分析看的话,其实就是几种状态。系统正常、系统故障、系统恢复。所以非常适合采用状态机去实现。
熔断设计一般都是采用类似AOP的模式,对于业务代码无侵入。所以非常像一个代理模式。会自动记录某个时间段错误次数,决定是否返回继续还是错误。
- 闭合状态 (Close)
代表当前下游后段服务是正常的,但是会开启一个计数器来记录失败的次数,当在一定的时间内超过失败次数的阈值,则将状态切换到断开状态。然后会开始一个超时时钟,当该时钟超过了该时间,则切换到半断开状态。超时时间的设定可以给系统一次修正调用失败的错误,回复到系统正常状态。 - 断开状态
该状态下代表系统不可用,对于请求过来的请求可以直接返回错误,但是更好的方式是cache住本次请求数据,然后对于整个系统用户来说返回一样的数据。 - 半开状态
允许系统一定的请求量调用服务,如果这些请求都调用成功,那么可以认为之前导致失败的错误已经修正,熔断器切到闭合状态。
半断开状态可以有效防止正在恢复中的服务被突然而来的大量请求拖垮。
实现熔断器模式可以使得系统更加稳定和有弹性,系统可以从错误中恢复,并且减少错误对系统的影响。可以快速地拒绝哪些试图可能导致错误的服务调用,避免等待超时或者永远不会返回结果来提高系统的响应时间。
具体的开源框架就是 Netflix 的开源项目Hystrix
熔断设计的重点
- 错误类型 。请求失败的原因可能很多,需要不同的情况采用不同的策略,熔断和重试一样,一般先走重试的策略,之后在打开熔断,有的是服务挂掉,这种就直接打开熔断。先重试后熔断。
- 日志监控。日志应该记录所有失败的情况,使得管理员能够监控使用熔断器保护的服务的执行情况
- 测试服务可用。如果服务宕机,使用熔断模式需要使用真实的用户进行测试服务可用。其实熔断器可以定时的去ping一下 服务的将康检测端口,来判断服务是否恢复。 比如机器对外的网络端口或者本级的port。之前就遇到 不小心把检测端口的API删除,导致服务正常启动但是就是没有用户流量进来。
- 手动重制。如果出现系统故障或者系统已经恢复,可以通过后台进行人工介入使系统进行恢复或者熔断器断开。
- 并发问题 一般来说,相同的熔断器可能会同时多个请求进行处理,所以不应该阻塞并发请求,尤其对结果进行统计的时候,应该成为一个共享的数据结构,一般使用无锁 atomic原子操作性能更好。
- 资源分区 对于有量级的系统来说,数据会进行分区,分库分表等操作,所以单一的熔断器可能会把所有分区进行标记不可用,这样就可能导致一会可用 一会不可用,所以需要对有问题的分区进行熔断,而不是对整体。
- 重试错误的请求,有些请求可能是参数错误的问题导致的,所以一般在设计的时候最好记录下出错的请求参数,并且需要被调用端支持幂等调用。
小结
本篇主要介绍了 熔断设计的解决的问题,其实主要还是实现系统调用层面的高可用,以此提升系统的稳定性。然后主要说了下熔断设计的几种状态,并且介绍了熔断设计的重点问题。最终我们都是在经过几次重试之后,然后进一步升级到熔断。