限流熔断技术选型:从Hystrix到Sentinel
相关工作。
高可用架构:Hystrix作为大家熟知的容错组件,最近宣布停止开发,很多人对其背景可能了解不多。作为Spring Cloud官方默认的熔断组件,您觉得Hystrix是出于哪些原因停止开发呢?
子衿/宿何:这个事情,我也是之前看媒体报道才了解到的。Hystrix是Netflix的一款开源限流组件,官方宣布停止在开源版本上提供新功能,作为开发者,觉得有点可惜,但仍要感谢Netflix之前以及现在正在为开源做的贡献。
关于Netflix为什么会宣布停止在开源版本上提供新功能,目前官方并没有给出原因,只是提供了一些解决方案。但我看到Netflix官方博客的一篇文章,也许能找到技术层面的考量:Netflix 现在正在探索更自动化的熔断方式。所以我们猜测Netflix内部会逐步不再使用Hystrix ,没有继续更新的动力;再加上 Hystrix 作为一个熔断降级组件已经非常稳定了,因此停止开发是可以理解的。另一个是非技术层面,技术的开源是需要业务的增长和完整的技术团队来支撑的,无论是国内还是国外,开源项目能否持续,依赖于企业在技术上是否能长期投入。博客原文地址[1]。
高可用架构:Hystrix官方推荐使用Resilience4j,你们是怎么看这个项目?
子衿/宿何:resilience4j 是一个比较轻量的熔断降级库。首先 resilience4j 的模块化做的比较好,将每个功能点(如熔断、限速器、自动重试)都拆成了单独的模块,这样整体结构很清晰,用户也只需要引入相应功能的依赖即可;另外resilience4j 是针对 Java 8 和函数式编程设计的,API 比较简洁优雅。同时与 Hystrix 相比,Resilience4j 增加了简单的限速器和自动重试特性,使用场景更加丰富。Resilience4j 属于一个新兴项目,社区也在蓬勃发展。总的来说,Resilience4j 是比较轻量的库,在较小较新的项目中使用还是比较方便的,但是 Resilience4j 只包含限流降级的基本场景,对于非常复杂的企业级服务架构可能无法很好地 cover 住;同时 Resilience4j 缺乏生产级别的配套设施(如提供规则管理和实时监控能力的控制台)。
高可用架构:Sentinel今年7月份开源,Github上已经有将近4K的Star,目前发布的最新版本是1.3,能否给高可用架构读者简单介绍一下Sentinel,比如相比于同类项目的优势,设计思想,主要模块以及如何快速接入等。
子衿/宿何:Sentinel 一款面向分布式服务架构的轻量级流量控制组件,主要以流量为切入点,从流量控制、熔断降级、系统自适应保护等多个维度来帮助用户保障服务的稳定性。
Sentinel 的核心思想:根据对应资源配置的规则来为资源执行相应的流控/降级/系统保护策略。在 Sentinel 中资源定义和规则配置是分离的。用户先通过 Sentinel API 给对应的业务逻辑定义资源,然后可以在需要的时候动态配置规则。
Sentinel 的优势和特性:
- 轻量级,核心库无多余依赖,性能损耗小。
- 方便接入,开源生态广泛。Sentinel 对 Dubbo、Spring Cloud、Web Servlet、gRPC 等常用框架提供适配模块,只需引入相应依赖并简单配置即可快速接入;同时针对自定义的场景 Sentinel 还提供低侵入性的注解资源定义方式,方便自定义接入。
- 丰富的流量控制场景。Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,流控维度包括流控指标、流控效果(塑形)、调用关系、热点、集群等各种维度,针对系统维度也提供自适应的保护机制。
- 易用的控制台,提供实时监控、机器发现、规则管理等能力。
- 完善的扩展性设计,提供多样化的 SPI 接口,方便用户根据需求给 Sentinel 添加自定义的逻辑。
Sentinel 与 Hystrix、resilience4j 的对比:(这个对比已经展示在Sentinel的Wiki页面[2],任何疑问,欢迎发起issue一起讨论)
高可用架构:作为流控的重要一环,能否简单介绍一下Sentinel内部是如何实现熔断的?能否给个简单的熔断器使用实例?
子衿/宿何:Sentinel 内部熔断的实现其实就是熔断器的思想。Sentinel 底层会通过优化的滑动窗口数据结构来实时统计所有资源的调用数据(通过 QPS、限流 QPS、异常数、RT 等)。若资源配置了熔断降级规则,那么调用时就会取出当前时刻的统计数据进行判断。当达到熔断阈值时会将熔断器置为开启状态,切断所有的请求,直到过了降级时间窗口后再重置熔断器,继续允许请求通过。
Sentinel 熔断降级支持以下几种指标:平均响应时间、秒级异常比率、分钟级异常数。在 Sentinel 中,我们一般将熔断降级与并发线程数限流相结合来对不稳定的服务调用进行熔断,防止出现级联错误。
由于Sentinel 的资源定义和规则配置是相分离的,因此只需要对资源配置熔断降级规则即可。比如我们定义了如下资源:
那么只需要配置如下规则:
如果接入了Sentinel 控制台,那么可以直接在 Sentinel 控制台上进行配置,更加方便:
高可用架构:限流相对比较麻烦,尤其是弹性伸缩的架构中,首先得知道系统的承载量,其次,如果横向伸缩了服务器,原有的限流策略未必适用。Sentinel的限流是怎么做的?有没有可能无需配置,自动感知,动态限流?Sentinel支持自定义限流策略,能否给个简单的使用实例?
子衿/宿何:一般来说,我们需要通过全链路压测来了解系统的容量,从而可以为限流规则的配置提供参考。Sentinel 支持多个维度的流量控制策略,可以覆盖不同的流量场景:
- 根据不同指标:QPS, 并发线程数等
- 根据调用关系:按调用来源限流、按调用链路限流、关联限流等
- 流量塑形控制效果:直接拒绝、冷启动模式、匀速器模式、预热排队模式等
- 不同的资源维度:服务接口、服务方法、热点参数、自定义资源
- 集群维度的分布式流量控制(即将发布)
流量具有实时性和不确定性,很难准确地进行预测。如何根据实时流量和系统指标来自适应地限流一直是Sentinel 在不断研究的方向。Sentinel 从 2016 年开始就在不断的探索智能化、自适应限流的可能性,目前开放出来的算法有基于 TCP BBR 的系统保护算法。系统自适应保护可以结合 load 等实时指标,自动探测当前系统水位是否超过系统的最大容量,只有在超出系统处理能力的时候才会发生限流。未来 Sentinel 还会推出更加智能化的自适应限流策略。
限流的使用同上面的降级一样简单,只需配置限流规则即可。以下是一个简单的示例,限制资源每秒的调用QPS 为 20:
高可用架构:Sentinel有基于Spring Boot实现的监控系统,支持哪些metric呢?监控数据是Sentinel主动上报吗?采样率是多少?上报时间间隔是多少?metric数据如何存储?时序数据库吗?能否把监控数据快速集成到现有的监控系统上,比如Zabbix或者Prometheus等等?是否支持自定义metric?能否给个简单的例子?
子衿/宿何:Sentinel 目前的监控支持 QPS、响应时间、限流数、异常数等几种指标。Sentinel 客户端每秒会把秒级的监控数据存储至本地日志,Sentinel 控制台进行拉取和聚合。在生产环境中,由于秒级监控数据的量非常大,我们一般将 metric 数据存储于列数据库或时序数据库中,并通过一些策略进行优化来保证监控存储和聚合的性能。
Sentinel 正在进行指标与监控标准化的相关工作,在完成标准化,抽出通用的 metric 接口后,即可快速对接 Zabbix 和 Prometheus 等监控系统,同时用户也可以方便地对接其它监控系统。
高可用架构:除了上面提到的功能外,Sentinel还有哪些有意思的特性值得读者了解?
子衿/宿何:Sentinel 的 专业流量控制[3] 相关的特性都值得大家关注,包括流量塑形[3]、系统自适应保护[4]、调用链路统计[5]、热点限流[6]。关于这些特性,我们也给出了链接,大家感兴趣的话去可以去对应的页面了解。
高可用架构:Sentinel目前有哪些案例,他们使用场景及效果能否简单介绍一下?
子衿/宿何:Sentinel源于阿里巴巴自身的生产实践,适用场景非常丰富,包括:
- 双十一零点持续峰值:限流、慢调用降级
- 秒杀(脉冲流量):限流、慢调用降级
- 消息队列削峰填谷:MQ 消费端可能会出现大批量的消息同时到达,若瞬时请求所有消息会导致系统负载过高。我们利用匀速器模式将消息突刺均摊到一段时间内,让系统负载保持在处理能力水位的同时尽可能地处理更多消息,从而起到“削峰填谷”的效果。
- 冷启动:当流量突然增大的时候,我们希望系统从空闲状态到繁忙状态的切换的时间长一些,即如果系统在此之前长期处于空闲的状态,我们希望处理请求的速率缓慢增加,经过预期的时间以后,到达系统处理请求速率的设定值;
- 热点商品自动探测、防护:自动统计访问频次最高的热点参数并进行流量控制;
- 集群流量不均匀:通过集群限流来解决集群各个机器的流量不均导致整体限流效果不精确的问题;
我们在10月30日上线了GA版本,目前已有不少企业用户在使用开源版本和云上版本的Sentinel,包括顺丰、vivo、每日优鲜、拼多多、易企秀等,我们也在社区发起了“who is using Sentinel”[7]的issue,可以去这个页面了解各家企业的使用场景。
高可用架构:Sentinel作为Spring Cloud Alibaba重要的开源组件,前后大概投入了多少人力成本呢?是否有专门的团队进行长期维护?未来有什么样的规划?
子衿/宿何:Sentinel 之所以能开源,并且提供稳定的限流降级功能,是因为站在了巨人的肩膀上,离不开阿里历届高可用架构团队的共同努力。2014年,高可用架构团队因实现了全链路压测,获得了当年的集团CTO大奖。
2014年获奖照片
Sentinel在开源过程中,对原有代码进行大量的重构、规范化,对模块结构进行了优化,增强了扩展性。目前,我们有专门的开源团队,对开源项目进行长期的维护和演进。
近期,Sentinel 推出了集群限流版本 1.4.0,提供了独有的灵活、高性能的集群限流模块。集群限流主要针对需要限制整个集群流量总量,但是由于单机流量不均匀而无法精确地限制总体流量的问题。用户可以利用 Sentinel 集群限流模块,结合自动化的管控策略来保障集群流量的稳定。自适应动态限流也是保障稳定性的重要一环。Sentinel 目前提供了基于 BBR 算法的系统自适应保护策略。
未来Sentinel 会继续在无规则容量保护的路上探索,提供更多自适应限流策略,更好地结合系统容量来进行流量控制。另外,Sentinel 也会支持更广泛的开源生态,适配 RxJava、Spring WebFlux 等 reactive 的组件;同时会抽出标准的指标和监控接口,方便对接 Prometheus 等常用的监控系统。最后,Sentinel 也会朝着 Cloud Native 的方向演进,引入多语言集群限流客户端支持,同时提供对 Service Mesh 的支持。
文中链接:
[1] https://medium.com/@NetflixTechBlog/performance-under-load-3e6fa9a60581
[2] https://github.com/alibaba/Sentinel/wiki/Guideline:-从-Hystrix-迁移到-Sentinel
[3] https://github.com/alibaba/Sentinel/wiki/流量控制
[4] https://github.com/alibaba/Sentinel/wiki/系统自适应限流
[5] https://github.com/alibaba/Sentinel/wiki/Sentinel工作主流程
[6] https://github.com/alibaba/Sentinel/wiki/热点参数限流
[7] https://github.com/alibaba/Sentinel/issues/18