自适应熔断与限流是在分布式系统中常用的机制,用于保护系统免受服务雪崩效应与突发流量影响。它能够根据系统的负载情况和性能指标自动调整限流策略,以确保系统能提供稳定可靠的服务,目前在业内已经有了不少的探索与实践。
限流主要的应用场景为应对流量激增的场景(如活动促销,外部流量攻击等)。如下图,当系统流量激增时,如不加以限制,可能会导致系统负载被打满,致使服务崩溃,最终导致服务不可用。
通过限流,仅允许部分流量的请求可以通过,其余请求会直接快速失败,即便突发流量出现时,服务始终仅承载部分请求,系统负载可控,保证了服务能稳定可用。
熔断主要的应用场景为依赖的服务出现故障时防止出现服务雪崩(如下游超时,db故障等)。如下图,当下游服务故障导致超时,由于长时间不响应会导致上游服务请求产生阻塞,导致系统资源增加(常见的如tomcat线程池、连接池等),如持续故障,则请求阻塞会持续增加导致上游系统线程池资源耗尽,导致上游服务不可用,并且会向上产生级联故障,最终因底层服务的故障导致整个链路的服务雪崩。
通过熔断可以在下游发生故障之后,针对下游的调用进行快速失败,这样就避免了系统资源因下游故障而耗尽,使系统保持可用,同时熔断后也会定期进行下游探测,当下游恢复后,会退出熔断,自动恢复下游调用。
传统熔断限流主要是客户端模式如hystrix, sentinel静态流控功能,存在着一些弊端:
自适应熔断限流整体方案
添加EnvoyFilter后触发同namespace下所有Pod的xDS推送,在自适应调节过程会频繁变更EnvoyFilter导致推送频率过高,mesh控制面Istio的负载也会大幅上升,因此针对Istio的源码进行了性能优化,在推送XDS时进行label匹配,仅会对label匹配的实例推送XDS配置。
由于在envoy上实现自适应熔断并无开源经验可借鉴,SRE熔断算法需要类似与基于概率的方式限流,envoy原生并没有概率限流的策略。经过研究与测试,采用超长token投递频率结合限流生效比例的方式模拟出概率限流的效果,经多次压测验证,误差稳定在2%范围内,满足实际熔断要求。
由于自适应熔断场景对熔断目标的粒度要求高,需要是API维度,由于熔断场景主要针对的是出口调用的场景,且熔断发生时下游并未返回报文,因此无法使用spring ServletRequest.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE)来获取接口路径,这种情况下当路径中存在变量时,会出现维度爆炸的问题。因此通过研发模板匹配EnvoyFilter,当接口开启熔断功能时会下发模板匹配EnvoyFilter,当向下游发起调用时会先通过模板匹配EnvoyFilter进行接口匹配,自适应熔断仅会作用在模板匹配通过的接口请求。
此外还做了许多的难点攻克与优化,如算法调优、istio监控指标定制、 envoy精细化限流失准问题和api server性能问题等
自适应限流设置没有复杂的规则参数设置,仅需选择功能开关的开启或关闭,并且支持实例级别的灰度。
自适应熔断设置支持API维度与站点维度,API与站点列表是根据监控信息自动提取的,且无额外规则参数设置,用户仅需关注开关的开启与关闭。
自适应限流记录详情中除了包含触发的基础的站点实例信息外还包含了触发恢复的原因、条件描述,及触发与恢复前后的监控指标快照,通过快照可以方便的进行问题排查与分析。如图上所示,当流量导致CPU飙升后,自适应限流会介入,使CPU负载降低直至趋近于设定的目标水位线,从而保障了服务的可用性。同时由于部分请求快速失败了,导致整体吞吐量实的提升。
自适应熔断记录详情与自适应限流详情类似,也是由基础信息与监控指标快照组成,通过快照可以发现当下游出现大量超时后,自适应熔断开始介入,大部分请求被快速失败,避免了服务被下游拖垮。
但与传统熔断不同的是,自适应熔断始终尽可能的往下游释放请求,当下游超时有所恢复时,流量也能快速实现恢复,在保证自身服务不被下游拖垮的同时,最大化的保证了业务的完整性。
目前我们已经完成了自适应限流与熔断的阶段性落地,完成了部分站点的试点与开启,后续也会进一步的探索,如自适应限流细化到接口层面,仅针对导致负载上升的接口进行自适应限流;进一步细化指标粒度,提升自适应策略触发与恢复的灵敏度等;使服务保障机制向更精准、更高效、更稳定的方向发展。
Chasen,现任基础框架研发专家