目录
- 熔断设计
- 限流设计
- 降级设计
- 框架选型
熔断设计
熔断器模式是用来防止应用程序不断地尝试执行可能会失败的操作,使得应用程序可以继续执行,而不会浪费 CPU 时间去等待长时间的超时产生。
时序图
(本图来自 Martin Fowler 的 Circuit Breaker)
熔断器的几种状态
闭合(Closed)状态:熔断器处于闭合状态时,会有一个基于时间的调用失败计数器,如果在这个时间内的失败次数超过了给定的阈值,那么将切换到断开状态。
断开(Open)状态:在断开状态下,对应用程序的请求会立即返回错误响应,而不调用后端的服务。当切到断开状态后,会开启一个超时时钟,当时间超过了该时间,将切到半开状态。
半开(Half-Open)状态:在半开状态下,允许应用程序一定数量的请求去调用服务。如果这些请求调用成功,那么熔断器将切换到闭合状态;如果有一定数量的请求调用失败,那么熔断器将切换到断开状态。
状态机
(本图来自 Martin Fowler 的 Circuit Breaker)
限流设计
限流是通过对并发访问进行限速,一旦达到限制的速率,就会触发相应的限流行为。目的是为了:应对突发的流量、保证系统在某个速度下的响应时间及可用性、节约成本等。
限流行为:
- 拒绝服务。把多出来的请求直接拒绝掉。
- 服务降级。关闭或是把后端服务做降级处理。
- 特权请求。把有限的资源分给VIP用户。
- 延时处理。用队列来缓冲大量请求。
- 弹性伸缩。动用自动化运维的方式对相应的服务做自动化的伸缩。
限流的实现方式
1、计数器方式
2、队列算法。入队速率波动,消费可以相对匀速处理,队列满则丢弃。具体可以分为普通队列、优先级队列、权重队列等,来应对不同的场景。
3、漏斗算法。相比于队列,增加了限流器。
4、令牌桶算法。在一个桶内按照一定的速率放入一些 token,然后,处理程序要处理请求时,需要拿到 token,才能处理;如果拿不到,则不处理。
5、基于响应时间的动态限流。 借鉴TCP 协议的拥塞控制的算法。
降级设计
降级设计,本质是为了解决资源不足和访问量过大的问题。在有限的资源下,为了能够扛住大量的请求,保障整个系统的平稳运行,就需要对系统进行降级操作,也就要暂时牺牲掉一些东西。
牺牲掉的东西:
- 降低一致性。从强一致性变成最终一致性。使用异步简化流程。
- 停止次要功能。停止访问不重要的功能,从而释放出更多的资源。
- 简化功能。把一些功能简化掉,比如,简化业务流程,或是不再返回全量数据,只返回部分数据
很难通过不侵入业务的方式来做到功能降级,要对业务进行仔细的梳理和分析。做好相应的应急预案。这些预案最好是写成代码可以快速地自动化或半自动化执行的。
确定降级触发条件:吞吐量过大、响应时间过慢、失败次数多过,有网络或是服务故障,等等。
梳理业务功能:哪些是重要的,哪些是可以牺牲掉的功能。
牺牲掉一致性,或是一些业务流程:对于读操作来说,使用缓存来解决,对于写操作来说,需要异步调用来解决。
降级功能的开关可以是可配置的开关项,例如可以动态配置在 Apollo 、zookeeper 等配置中心。
框架选型
主流框架:
项目现状
Hystrix: 进入维护模式,不再主动更新版本,推荐使用Resilience4j。由 Netflix 公司维护,现在正在探索更自动化的熔断方式。
Resilience4j: 个人开发者维护,新兴项目,社区也在蓬勃发展。
Sentinel: 阿里维护,集团内部大量应用,社区也在蓬勃发展
三者都是 spring 官方推荐的框架选择
其他方面对比
Hystrix 的关注点在于以 隔离 和 熔断 为主的容错机制,超时或被熔断的调用将会快速失败,并可以提供 fallback 机制。
resilience4j 是一个比较轻量的熔断降级库,除了Vavr,它没有任何其他外部库依赖项。相比较于Hystrix,resilience4j 是针对 Java 8 和函数式编程设计的,API 比较简洁优雅。同时还增加了简单的限速器和自动重试特性,使用场景更加丰富。Resilience4j 是比较轻量的库,适用于在较小较新的项目,但是 Resilience4j 只包含限流降级的基本场景,可能不太适用于非常复杂的企业级服务架构,没有经历过大规模,高并发场景的洗礼。同时 Resilience4j 缺乏生产级别的配套设施(如提供规则管理和实时监控能力的控制台)。
相比Hystrix的关注点在于隔离和熔断, Sentinel注重流量塑形、系统保护、熔断降级等多样化的场景,对脉冲流量的秒杀、持续洪峰的零点双十一、热点商品自动探测控制、削峰填谷、针对集群分布不均匀的集群限流、冷启动、根据容量流量自适应的系统保护等专业场景。
Sentinel 与 Hystrix 的详细对比:https://github.com/alibaba/Sentinel/wiki/Sentinel-%E4%B8%8E-Hystrix-%E7%9A%84%E5%AF%B9%E6%AF%94
引用
1.《左耳听风》专栏:https://time.geekbang.org/column/intro/48
2. https://github.com/alibaba/Sentinel/wiki