水漫天飞,月赚亏损,没有什么可以无限发展,我们的系统服务能力是一样的。当流量持续增长,达到或超过业务本身的承载范围时,建立系统业务的自我保护机制就变得非常重要。本文希望通过最通俗的解释和恰当的例子,告诉大家什么是限流、降级和熔断。Part1限流-自知与远见本文希望通过最通俗的解释和恰当的例子,向大家展示什么是限流、降级、熔断。一是自身的承载能力,二是依赖方的服务能力。其实两者都是从现行制度的角度来看的。1.1自知被动限流我的能力就那么大,只能服务那么多的客户!系统需要清楚地了解自身的承载能力,并适当拒绝超出承载能力的额外呼叫。而如何衡量系统的承载能力是一个问题。一般来说,我们有两种常见的解决方案:一种是定义阈值和规则,另一种是自适应限流策略。阈值和规则是所有者通过对业务的控制以及自身存储和连接的现状,根据人工经验制定的。这样的策略一般不会造成什么大问题,但是不够灵活,对请求反馈和资源利用的敏感度不够。相比之下,自适应策略是一种动态限流策略,它是根据系统当前的运行状态,通过动态调整限流阈值,在机器资源和流量处理之间找到平衡。例如阿里开源的Sentinel限流器,支持动态限流策略[1]:负载自适应:系统的load1作为启发式指标,实现自适应系统保护。只有当系统load1超过设定的启发值,并且系统当前并发线程数超过预估的系统容量时,才会触发系统保护。CPU使用率:当系统CPU使用率超过阈值时,会触发系统保护(取值范围0.0-1.0),比较敏感。平均RT:当单机所有入口流量的平均RT达到阈值时,触发系统保护,单位为毫秒。并发线程数:当单机所有入口流量的并发线程数达到阈值时,触发系统保护。IngressQPS:当单机所有Ingress流量的QPS达到阈值时,触发系统保护。1.2有源限流小伙伴能力有限,我的要求也有限!需要对下游依赖系统的服务能力有一个准确的判断。对于服务能力较弱的下游系统,还是要有一点洞察力的吧?因为绝大多数业务系统都不是独立存在的,而是依赖于很多其他的系统。这些依赖方的服务能力就像是木桶的短板,限制了当前系统的处理能力。这时候就需要对下游进行整体考虑。因此,集群限流和单机限流一起使用是很有必要的,尤其是当下游服??务的实例数和服务能力与当前系统存在较大差距时,集群限流还是很有必要的。一种方案:通过收集服务节点的请求日志,统计请求量,通过限流配置控制节点限流逻辑:摘自:微服务治理:系统、架构与实践我称之为后限流,即收集各节点的请求量,并与设定的阈值进行比较,超过则反馈给各节点,依靠单机限流进行比例限流。另一种解决方案:它是一个限流的通用控制服务。根据配置产生token,然后各个节点消费token。只有正常获取token后才能继续业务:摘自:Sentinel我称之为前置限流,就是预先确定和分配的。Token取消了汇总反馈的处理机制。相比较而言,这种控制方式还是比较精确和优雅的。1.3同步转异步的小伙伴虽然能力有限,但是态度很好,加班加点;还有我们的客户也很友好,比较认同等等。一个很经典的例子就是第三方支付平台的还款业务。同学们应该都有体会,一般支付完成后要等一段时间才会收到取消通知。这种延迟的潜在逻辑是什么?一般来说,金融机构的服务接口由于对数据一致性和系统稳定性的要求,在性能上可能不如互联网公司的系统。那么,到了月初和月末的还款高峰期,如果把扶持成功用户的注销请求全部压给机构,后果可想而知。但是对于用户来说,整个流程是可以拆分的,用户只需要完成支付操作即可。至于最终结果,可以允许延迟通知。所以,基本上,金融网关在代理核销的处理上是异步的,即先落地各个业务的核销请求,然后异步限速轮询待办单据,再与代理核销进行交互。机构。其实不仅是金融领域,只要我们的业务处理速度有差异,流程可以拆分,都可以考虑这种架构思路,缓解系统压力,保证业务可用性。Part2降级-丢车险帅事故突如其来,能力有限,只能专注于几个重要的客户服务!那么,哪些环节需要降级,哪些环节可以降级呢?当整个业务处于高峰期或活动脉冲期,服务负载很高,接近服务负载阈值时,可以考虑降级服务,以保证主要功能的可用性。可以降级的链接必须是非核心链接,比如网购场景中的扣分。如果扣分环节降级,大部分支付功能不会受到影响。那么,我们在系统中一般采用的降级方案有哪些呢?1、页面降级:即从用户操作页面开始操作,直接限制切断某个功能的入口:从页面入口降级点链接如上图所示,在该业务场景下,是否使用points是在页面渲染阶段决定的,并返回上一节进行页面拼接。当我们需要对其进行降级时,我们会通过控制平台来切换降级开关。系统读取启用降级后,会返回上次积分降级的标志,前端不再显示扣分入口。即从入口处切断集成环节的执行,达到降级的目的。2.存储降级:使用缓存对频繁操作的存储进行降级https://blog.csdn.net/di_ko/article/details/118058080对于写多读少的秒杀业务场景,对DB的压力是非常高是的,一般我们会采用上图所示的缓存架构,用缓存操作代替DB操作,用异步MQ代替同步接口,这也是一种存储降级行为。3.阅读降级:针对非核心信息的阅读请求,微信抢红包场景禁用。红包列表的展示属于抢红包的非核心环节。可以直接禁用信息读取。4.写降级:服务请求汇总,直接禁止相关写操作,一句话概括了降级的核心——丢车保帅。整个业务链路的稳定和持续可用,换来的是部分体验的损失。Part3断路器——大局伙伴有难,不能把别人逼到自己的死胡同,也不要拖累自己!出于人道主义,我不得不时不时地问一句,你还好吗?熔断机制之所以被冠以大局的美名,是因为它要解决的问题是级联故障和服务雪崩!在分布式环境中,异常是常态。如上图所示,当服务C出现调用异常时,服务B会出现大量的请求超时和调用延迟,这些调用也需要占用系统资源。当大量请求积压时,服务B的线程池等资源也会被耗尽,最终可能导致整个服务链路雪崩。因此,当服务C出现异常时,为了整个链路的健康,适当暂停对服务C的调用,并持续监控其接口是否恢复,是非常有必要的。上述对C的处理过程为融合。Hystrix官方熔断流程[2]从上图可以看出,熔断操作有3个关键点:不进行远程调用,但调用结果需要有一个替代的逻辑断路器恢复,具有适当的检测机制来结束断路器并恢复正常的服务调用。在《在所依赖存储不授信的场景下实现柔性事务降级》一文中提到,我们的分布式事务会依赖底层存储进行元数据存储和一致性校验。但是底层存储的稳定性略有不足,这就涉及到服务熔断的处理:当我们通过关键字监控检测到底层存储异常运行到一定阈值时,就会通过脚本触发切换操作。开启这个开关的作用是放弃底层存储,直接进入底层消息队列,保证大部分请求都能正常处理。在开始开发期间,使用测试线程测试底层存储是否恢复。当检测到存储恢复正常时,交换机恢复正常链路。(这一步还没有实现,已经手动替换了)
