gitbook/SRE实战手册/docs/216613.md
2022-09-03 22:05:03 +08:00

13 KiB
Raw Blame History

05 | 案例落地SLO时还需要考虑哪些因素

你好,我是赵成,欢迎回来。

前面几节课我们按照层层递进的思路从可用性讲到SLI和SLO再到SLO所对应的Error Budget策略。掌握了这些内容也就为我们建设SRE体系打下了一个稳固的基础。

今天我用一个电商系统的案例带着你从头开始一步一步系统性地设定SLO一方面巩固我们前面所学的内容另一方面继续和你分享一些我在实践中总结的注意事项。

案例背景

我先来给你介绍下电商系统案例的基础情况,框定下我们今天要讨论的内容范围。

一般来说,电商系统一定有一个或几个核心服务,比如要给用户提供商品选择、搜索和购买的服务等。但我们知道,大部分用户并不是上来就购买,而是会有一个访问的过程,他们会先登录,再搜索,然后访问一个或多个商品详情介绍,决定是放到购物车候选,还是选择物流地址后直接下单,最后支付购买。

这条从登录到购买的链路,我们一般称之为系统的核心链路Critical Path系统或网站就是依靠这样一条访问链路为用户提供了购买商品的服务能力。

至于电商系统的其它页面或能力,比如网站政策、新手指导、开店指南等等,这些对用户购买服务不会造成太大影响的,相对于核心链路来说,它的重要性就相对低一些。

我们要给电商系统设定SLO大的原则就是先设定核心链路的SLO然后根据核心链路进行SLO的分解。接下来,我们就一步步拆解动作,看看怎么实现这个目标。

核心链路:确定核心应用与强弱依赖关系

要确定核心链路的SLO我们得先找到核心链路。怎么实现呢

我们可以先通过全链路跟踪这样的技术手段找出所有相关应用,也就是呈现出调用关系的拓扑图,下面我给了一张图,这个图你应该并不陌生,这是亚马逊电商分布式系统的真实调用关系拓扑图。之所以这么复杂,是因为即使是单条路径,它实际覆盖的应用也是很多的,特别是对于大型的分布式业务系统,可能会有几十甚至上百个路径,这些应用之间的依赖关系也特别复杂。


面对这样复杂的应用关系,是不是感觉无从下手?那就继续来做精简,也就是区分哪些是核心应用,哪些是非核心应用。这是要根据业务场景和特点来决定的,基本上需要对每个应用逐个进行分析和讨论。这个过程可能要投入大量的人工来才能完成,但这个是基础,虽然繁琐且费时费力,也一定要做。

这里我简单举个例子说明。

比如用户访问商品详情的时候,会同时展现商品评价信息,但是这些信息不展现,对于用户选择商品也不会造成非常大影响,特别是在双十一大促这样的场景中,用户在这个时刻的目的很明确,就是购买商品,并不是看评价。所以类似商品评价的应用是可以降级的,或者短时间不提供服务。那这种不影响核心业务的应用就可以归为非核心应用。

相反的像商品SKU或优惠券这样的应用直接决定了用户最终的购买金额这种应用在任何时刻都要保持高可用。那这种必须是高可用的应用就是核心应用。

就这样,我们需要投入一些精力一一来看,确定哪些是核心应用,哪些是非核心应用。梳理完成后,针对电商系统,我们大概可以得到一个类似下图的简化拓扑关系(当然了,这里仍然是示例,相对简化,主要是保证效果上一目了然)。

这张图就呈现出一条典型的电商交易的关键路径,其中绿色部分为核心应用,蓝色部分为非核心应用。

这个时候,我们又要进行关键的一步了,就是确认强弱依赖。

核心应用之间的依赖关系,我们称之为强依赖,而其它应用之间的依赖关系,我们称之为弱依赖,这里就包含两种关系,一种是核心应用与非核心应用之间的依赖,另一种是非核心应用之间的依赖。

好了至此我们就确定了这个电商系统的核心应用和强弱依赖关系也就是找到了这个系统的核心链路。那我们就可以设定这条核心链路的SLO了并基于此设定其他的SLO。这时应该遵循哪些原则呢

设定SLO有哪些原则

针对核心和非核心应用以及强弱依赖关系我们在设定SLO时的要求也是不同的具体来说可以采取下面4个原则。

第一核心应用的SLO要更严格非核心应用可以放宽。 这么做就是为了确保SRE的精力能够更多地关注在核心业务上。

第二强依赖之间的核心应用SLO要一致。 比如下单的Buy应用要依赖Coupon这个促销应用我们要求下单成功率的SLO要99.95%如果Coupon只有99.9%那很显然下单成功率是达不成目标的所以我们就会要求Coupon的成功率SLO也要达到99.95% 。

第三,弱依赖中,核心应用对非核心的依赖,要有降级、熔断和限流等服务治理手段。 这样做是为了避免由非核心应用的异常而导致核心应用SLO不达标。

第四Error Budget策略核心应用的错误预算要共享就是如果某个核心应用错误预算消耗完SLO没有达成那整条链路原则上是要全部暂停操作的,因为对于用户来说,他不会判断是因为哪个应用有问题,导致的体验或感受不好。所以,单个应用的错误预算消耗完,都要停止变更,等问题完全解决再恢复变更。当然,也可以根据实际情况适当宽松,如果某个核心应用自身预算充足,且变更不影响核心链路功能,也可以按照自己的节奏继续做变更。这一点,你可以根据业务情况自行判断。

如何验证核心链路的SLO

梳理出系统的核心链路并设定好SLO后我们需要一些手段来进行验证。这里我给你介绍两种手段一种是容量压测另一种就是Chaos Engineering也就是混沌工程。

容量压测

我们先来看容量压测。容量压测的主要作用就是看SLO中的Volume也就是容量目标是否可以达成。对于一般的业务系统我们都会用QPS和TPS来表示系统容量得到了容量这个指标你就可以在平时观察应用或系统运行的容量水位情况。比如我们设定容量的SLO是5000 QPS如果日常达到4500也就是SLO的90%,我们认为这个水位状态下,就要启动扩容,提前应对更大的访问流量。

容量压测的另一个作用,就是看在极端的容量场景下,验证我们前面说到的限流降级策略是否可以生效。

我们看上面电商交易的关键路径图以Detail商品详情页和Comment商品评论这两个应用之间的弱依赖关系为例。从弱依赖的原则上讲如果Comment出现被调用次数过多超时或失败是不能影响Detail这个核心应用的这时我们就要看这两个应用之间对应的降级策略是否生效如果生效业务流程是不会阻塞的如果没有生效那这条链路的成功率就会马上降下来。

另外还有一种场景如果某个非核心应用调用Detail的次数突然激增对于Detail来说它自身的限流保护机制要发挥作用确保自己不会被外部流量随意打垮。

其实类似上述这两种场景,在分布式系统中仅仅靠分析或画架构图是无法暴露出来的,因为业务变更每天都在做,应用之间的调用关系和调用量也在随时发生变化。这时候就需要有容量压测这样的手段来模拟验证,进而暴露依赖关系问题。并且,有些问题必须要在极端场景下模拟才能验证出问题,比如各种服务治理措施,只有在大流量高并发的压力测试下,才能被验证出是否有效。

Chaos Engineering-混沌工程

好了,接下来看第二种混沌工程。

我们知道,现在混沌功能非常流行,因为它可以帮助我们做到在线上模拟真实的故障,做线上应急演练,提前发现隐患。很多公司都很推崇这种方法并在积极学习落地中。

其实,刚才我们讲容量压测也提到,容量压测是模拟线上真实的用户访问行为的,但是压测过程中,如果我们模拟极端场景,可能也会造成异常发生,但这时的异常是被动发生的,不过从效果上来讲,其实跟混沌工程就很相似了。只不过,混沌工程是模拟故障发生场景,主动产生线上异常和故障。

那我们怎么把混沌工程应用在SRE中呢一般来说故障发生的层面不同我们采取的方式也会不同。

这里我简单介绍一下比如对于机房故障有些大厂会直接模拟断电这样的场景看机房是否可以切换到双活或备用机房在网络层面我们会模拟丢包或网卡流量打满硬件和系统层面可能故意把一块磁盘写满或者把CPU跑满甚至直接把一个服务器重启应用层面更多地会做一些故障注入比如增加某个接口时延直接返回错误异常线程池跑满甚至一个应用集群直接下线一半或更多机器等。

其实混沌工程也是一个非常复杂的系统化工程,因为要在线上制造故障,或多或少都要对线上业务造成影响,如果模拟故障造成的真实影响超过了预估影响,也要能够快速隔离,并快速恢复正常业务。即使是在稳定性体系已经非常完善的情况下,对于混沌工程的实施也要极为谨慎小心。对于一个模拟策略上线实施,一定是在一个隔离的环境中经过了大量反复验证,包括异常情况下的恢复预案实施,确保影响可控之后,在经过多方团队评审或验证,才最终在线上实施。

从这个角度来讲SRE和混沌工程是什么关系就非常清晰了**混沌工程是SRE稳定性体系建设的高级阶段**一定是SRE体系在服务治理、容量压测、链路跟踪、监控告警、运维自动化等相对基础和必需的部分非常完善的情况下才会考虑的。

所以,引入混沌工程手段要非常慎重,我建议大可不必跟风过早引入,还是优先一步步打好基础再做考虑。

应该在什么时机做系统验证?

我们有了验证整个系统SLO的手段但是我们可以看到这两个手段都是要在生产系统上直接实施的为了保证我们的业务正常运行那我们应该选择在什么时机以及什么条件下做系统验证呢

我们可以参考Google给出的建议。

核心就是错误预算充足就可以尝试尽量避开错误预算不足的时间段。因为在正常业务下我们要完成SLO已经有很大的压力了不能再给系统稳定性增加新的风险。

同时,我们还要评估故障模拟带来的影响,比如,是否会损害到公司收益?是否会损害用户体验相关的指标?如果造成的业务影响很大,那就要把引入方案进行粒度细化,分步骤,避免造成不可预估的损失。

这里,我和团队通常的做法,就是选择凌晨,业务量相对较小的情况下做演练。这样即使出现问题,影响面也可控,而且会有比较充足的时间执行恢复操作,同时,在做较大规模的全站演练前,比如全链路的压测,会做单链路和单业务的单独演练,只有单链路全部演练通过,才会执行更大规模的多链路和全链路同时演练。

总之,生产系统的稳定性在任何时候,都是最高优先级要保证的,决不能因为演练导致系统异常或故障,这也是不被允许的。所以,一定要选择合适的时机,在有充分准备和预案的情况下实施各类验证工作。

总结

今天我们结合一个电商案例讨论了在落地SLO时还要考虑的一些实际因素。你需要重点掌握以下4点

  1. 先设定核心链路的SLO然后根据核心链路进行SLO的分解。
  2. 确定一个系统的核心链路,关键是确认核心应用和非核心应用,以及强弱依赖关系。这个过程在初始执行时,需要大量人工投入和分析,但是这个过程不能忽略。
  3. 强依赖的核心应用SLO必须与核心链路SLO一致弱依赖的非核心应用SLO可以降低但是必须要有对应的限流降级等服务治理手段。
  4. 通过容量压测和混沌工程等手段,对上述过程进行验证,但是一定要在错误预算充足的情况下执行。

思考题

最后,给你留一个思考题。

我们知道不同的业务场景考虑的限制因素也是不同的对SLO设定也是一样的。本节课我们分享了一个电商业务应该要考虑的因素你是不是可以按照这个思路分享一个不同于电商的业务场景应该或可能要考虑哪些特殊因素呢

期待在留言区看到你的思考,也欢迎你把今天的内容分享给身边的朋友。

我是赵成,我们下节课见。