引言
面向失败设计的核心理念在于以一个悲观的心态出发,假设系统地任何组件都有可能在某个时刻都会发生和预计不吻合的情况,为这些不符合预期的情况(failure)做好准备。然而,这个思想的前提在于,需要设计者,有足够丰富的经验,能够把可能出现的状况识别出来。
通常来说,"状况”可以分为两个级别的,一个是系统级别的状况,例如,对容量的考虑,对数据冗余的考虑等,对于这种问题,已经有了系统的研究领域,可以在系统开始设计的时候,就把这些可能的突发情况考虑进去,这种情况,不是我们这篇文章的讨论重点;还有一种状况,这种状况散落在各个环节,它们只是一个“知识点”,或者”经验教训”,甚至只是一个业务的预备计划,它们并没有规律。所以,我们需要一个系统,把这些状况,系统地沉淀下来,在关键时候,能够在复杂的情况中快速定位出问题,并且准确的执行应对的方案。
阿里巴巴从2012年开始系统的沉淀这些”状况”以及他们的应对方案,到今天已经第6个年头了。在这6年中,沉淀出了一系列的有特色的理论以及成熟的预案平台系统。这套系统,覆盖了阿里巴巴4000多个系统,支撑了电商交易的所有核心场景。阿里巴巴也通过这套系统,从容的应对了6次电商领域规模最大,情况最复杂的双十一。
这篇文章,将会介绍如何把结构化状况以及应对方式,从而得以以系统地方式沉淀积累,成为可复用的预案;最后,文章会结合阿里巴巴10年大促的实践,给出实践预案的原则性建议。
什么是预案
一个系统在上线的过程中,可能会经过下面几个步骤:
这些预案在足够成熟的情况下,可以由系统自动探测并且执行;也有相当大的部分需要人工的干涉。对于后者,我们可以遵循下面的原则来把这些预案尽可能全的搜集起来:每一个阶段中,都可能产生预案。例如,采取微服务的策略,拆分应用,而服务之间有相互调用的关系,我们则必须为相互依赖的微服务不稳定或者不可用的做出预案,做出熔断降级或者限制调用的准备;如果我们在设计的时候考虑到了单点问题,我们就必须为在紧急的情况下切换主备做好准备;同理,如果上线前,这个服务准备了机器部署,那么我们就必须为真实流量高于服务容量做好预案。
- “有前提条件,有预案”。举一个例子,有一个系统,它能够顺利工作的前提是,它的处理能力在每秒1000个请求。当请求超过1000个之后,这个系统就会堆积任务,无法处理。这个相当于我们程序中的”assert”语句,我们必须通过限流或者其它的手段,来保证这个系统真正处理的请求,不会超过1000个。
- “需要人工干涉的操作环节,就需要准备预案“。从历史数据来看,不少的系统不可用是由于人执行变更的时候造成的。如果这个人操作的环节,可以由系统自动执行,这是最理想的情况;即使无法被系统执行,如果有一个固定的操作流程,可以确保操作的正确性,也能够大大的减低问题的产生。
- “故障预案“。故障的复盘,总结出来的经验操作,也是预案的重要来源。
- “业务预案”。预案还有一种重要的来源,是和业务强相关的线上变更。举个例子,在双十一零点的时候,为了确保系统的稳定性,需要把推荐降级掉。这个业务变更,就是一种预案。
预案的标准
一个完整的预案,应该包含下面几个要素:对解决的问题的描述;执行预案的条件;执行的动作;校验的方式;以及把各个涉及角色串联起来的工作流。
一个成熟的预案,具备下面几个特征:
清晰的判定条件
一个预案,能够沉淀到系统之中,要满足充分的条件。即,通过特定的表征,可以确定,再这个情况下,可以执行某个行为。两者是一个充分条件的关系。例如,仅仅凭”系统响应时间变慢”这个现象,我们不能做出把数据库切成冷备的决策,因为两者没有明确的指定关系;而“当上海的用户交易成功率下跌50%,其它地区的用户交易成功率无明显的波动”的表征的时候,我们可以做出把上海的买家的流量切到杭州区的决策。再比如,业务决定,“晚上20:00把页面的banner换为红色”,那么到了晚上8点,我们就可以执行这个把页面banner变红的方案。
当条件足够成熟的时候,我们可以把这个预案沉淀到系统之中去,由系统判定,目前满足这个条件,从而自动执行对应的方案。如果还不够成熟,可以加入人工的判断。这种情况,往往需要有对应准确的监控,以及经验的阈值。随着算法的不断发展,这些预案的比例也会占得越来越多。
一致的执行
由于预案本身就有应急的特性。它的执行必须是高效,准确。目前大部分的系统是分布式的,这更增加了它的难度。例如,在某个场景下,需要打开业务开关,这个业务开关是通过REST服务,在各个应用实例上执行。我们需要保证这个开关要快速的执行,并且每台机器上的结果都要一致,不能存在不确定性,例如,发生部分机器的开关打开成功,部分机器的开关不成功的情况。
可量化的校验方式
当预案执行完毕之后,要能够快速的得知执行的情况。预案的执行校验,一般分为两层,一层是系统层面的执行效果,通常表现为系统行为,例如,恢复供电,系统的开关打开等;第二层是业务效果,一般表现在业务含义上,例如,系统地某个业务开关打开后,业务是否走了对应的逻辑,表现出了不同的业务效果等。这就对应了两种校验。前者的校验可以通过系统校验,后者则需要业务方的参与。
隔离的工作流
在线上,一个预案从决策到执行,往往是涉及到多个环节,多个角色的。一个好的平台,应该能做到各个角色环节尽量隔离,做到每个角色只需要关注自己需要关注的情况,明确的知道自己在什么情况下需要做什么。这个就需要系统清晰的定义工作流,把信息做有效的隔离,如下图所示:
通过隔离工作流,同一个预案的执行过程中,每个角色都只需要关注自己的行为,而不需要受到别人的干扰。这样,才能够在突发的情况下,效率最高的处理自己的事情。
预案的生命周期
预案的也有它的生命周期,一般来说,我们可以认为预案由梳理预案,开发预案,测试,上线,演练,最后下线的几个阶段。
梳理预案:我们的系统没增加一个功能,可能带来的风险点,都需要被定位出来。这些风险点,我们通过评估它的影响,来为之准备应对的方案。
开发预案:当一个风险点被梳理出来,我们需要准备预案的应对方案。这个应对方案有可能是业务中的一个开关,也有可能是执行脚本,甚至是文字描述的执行步骤。无论这些应对方式是否可以系统化的执行,都要将他们中性且客观的沉淀下来。
测试:开发完毕之后,需要测试这个预案的执行效果是否如预期所示。这个测试,分为两种级别的测试,一个是系统层面的测试,例如业务的开关是否推送成功等;一个是业务含义的测试,例如这个开关执行之后,系统的表现行为是否如预期所示。
上线:测试完毕之后,就可以再线上运行了。
演练:这个是非常容易遗漏的一环。预案的正确性需要长期的维护,它可能再线上很长的时间并不会被执行到,但是我们必须要保证它是一个有效的预案。所以我们需要在线上进行定时的演练,保证预案的有效性。
下线: 随着业务,结构的发展,预案也会失效。
预案的成熟度模型
我们可以把预案的成熟度分为几个等级:
预案在阿里巴巴的最佳实践
阿里巴巴在这几年中,也沉淀了一套预案的最佳实践,在不同的阶段,有不同的重点。
在大促,活动开展之前,对已知风险点,必须有对应的预案。阿里巴巴针对重要的业务链路,组织涉及的每个系统进行横向梳理。对于梳理出来的可能的风险点,都必须有对应的预案产出;对于曾经发生过的故障,也必须有对应的预案沉淀下来。最后,这些预案会集中在预案平台中统一管理,这些预案,可以根据业务,场景,都方便的定位到。
在准备大促的时候,预案必须经过线上的校验。虽然预案是有触发条件的,但是我们也必须保证预案的正确性。因为预案本来就是在紧急情况下执行的一个措施,它的不确定性必须控制在最小的范围之内。
定期演练预案。我们不能期待一个未经验证的预案,在紧急问题发生的时候,就能够使用。例如,在系统设计的时候,考虑到了对数据库的冷备库切换的预案。当系统落地之后,我们就验证了这个预案的正确性。但是随着业务的发展,我们对数据库增加了表单,我们如何确保预案能够正确地同步这些变更了?所以,我们也必须对这些预案进行持续的验证。最后,预案必须要定期的演练。这个演练,不仅仅包含预案的正确性,还包括对紧急情况的预演。
预案的报表,也是非常重要的。因为这是一个直接的量化标准。可以直接看到预案的演练情况。
文章来源:AlibabaTechQA
开发者社区整理