✪ 2.1.2 监控体系
我认为监控体系的建立是稳定性防线体系建设中最重要,也是难度最大的一环,线上的系统每天都处于不断的变化中,这种变化既来自自身的应用迭代,也来自上游业务的不断调整,随着时间的发展,业务的复杂度会变的越来越高,这时候就需要一个非常完善的监控机制,能帮我们快速预防和发现线上问题,如果没有一个好的监控体系,那么维护系统稳定性根本无从谈起。
虽然说起来简单,但是要实际建立一个完善的监控体系却是一个非常之难的事情,即使现有的监控体系非常完善,但是随着时间的不断推移,现有的监控必然会随之腐化,重新完善整套监控体系需要投入很大的人力成本(比如人员流动后,原有监控的运行体系没有交接,可能需要重新编写等)。
如何去建立以及维护一套完整的监控体系,其中的方法比较细节,在此列举几个我认为比较关键的内容:
⍟ 监控覆盖面
覆盖面是评判体系是否足够优秀的第一个标准,对于业务特别复杂的接口,覆盖面越大,发现问题的概率就越高,但是对于历史包袱较重或业务比较复杂的系统,覆盖面做到百分百是不可能的,这里我从增量和存量两个角度讨论一下如何提高监控覆盖面:
- 存量:梳理业务模型,盘点所有链路,优先从重要链路,例如从能影响线上流程或导致资损的链路开始,存量的监控盘点是一个持续不断的过程,随着时间的推移,我们的努力会使监控链路不断完善。
- 增量:相较于存量,增量则更好处理一些,新业务上线时是否需要监控,可以通过CR或群体评审来决定。
其中,可能有的存量问题链路较难发现,或短时间内影响面较小,导致无人关注,或者一直梳理不出来,等到某一天问题积压爆发,这个问题在重存储的系统中非常明显,我们正在讨论一种解决方案:数据聚合分析,即从数据共性角度,判断出非法数据,进而判断出非法链路。
⍟ 降噪 & 健康度
降噪是在监控中最让人头疼的一环,估计很多同学都有过体会,大多数情况下,线上告警出的问题并不会影响线上稳定性,这种告警一旦过多,容易让人逐渐放松警惕,当真正出现重大故障时往往不能第一时间发现。告警的有效性,就是我们常说的“监控健康度”。
很多成熟的监控产品,会将监控健康度作为一个重要的指标,当监控的告警有效性很低时,会停用监控先进行维护,关于如何进行监控降噪提高健康度,我个人经验有如下几点:
- 提高维护效率:一个复杂的系统往往有很多的监控,每种监控可能都处理不同的业务,如果全部依赖稳定性同学进行处理,显然是不可行的,应当将监控按不同的业务维度分发给团队内的同学,避免出现一个人处理一大批监控,最终处理不过来导致告警积压,告警效率降低。
- 及时降噪:明确分工之后,一旦监控发现告警,对应的负责人要及时处理,一般来说,需要人为check的监控告警积压数量不能超过20条,一旦超过就会极大的降低维护人员的工作效率,这种情况下要及时沟通,联系团队内其他同学安排时间协助排查;当发现需要降噪的数据时,要及时更新过滤规则,保证监控正常迭代。
⍟ 定时统计 & 复盘
团队内部要针对现有的监控进行定期盘点,健康度过低的监控要及时分析原因,并判断是否可以继续启用,不合理的监控关掉,避免混淆视听和增加监控成本。
✪ 2.1.3 流程规范
在日常中,相信大家不难发现,一些大故障,往往都有几个共性:
- 一把梭:绝大多数大故障的特性,这种问题常发生于配置推送类的操作,比如很多同学为了图快,直接通过预案直接推送配置,或代码中有推送配置等,也有在变更发布中,没有认真评估好变更的风险,灰度批次较少导致大故障,换句话说,灰度的批次和时间越长,导致大故障的概率就越低。
- 疏忽大意:发布时没有关注系统核心指标,虽然说灰度可以避免绝大多数的重大故障,但有些重大问题如果在灰度没有及时发现,等接近全部完成时爆发出来的话,本质上和“一把梭”没有任何的区别,这种情况常见于很多小流量应用中,即使一批机器也能扛起全部的流量,如果前面几批都挂掉了,除非看大盘,否则不会有任何的感知,但是最后一批发完之后,就直接报大故障了。
因此,严格的流程规范,会帮助我们及时发现和避免很多本不应该有的故障,当前阿里集团的安全生产团队已经将常见的几乎所有变更流程都进行了管控,内部如Aone、ChangeFree等平台已经进行了严格的平台化的规范,只要遵循线上正常的发布流程并加以防范,基本上不会出现特别大的故障,简单说一下我认为比较关键的几个流程:
- Code Review:CR想必大家都做过,但是不应该只局限于“Code”,任何会在线上产生变化的变更,都应该有人Review,但是这一步过度依赖人为,虽然有一些代码静态分析的工具,但是由于业务场景的复杂性,这一步虽然不能完全做到100%的准确,但是仍可能发现一些风险和规避一些低端的问题,同时,有经验的同学可以从底层代码优化和建模的角度,降低应用的熵增速度。
- 测试回归:靠人工的check无法达到太高的准确度,那么就需要靠平时测试同学积累起来的测试用例进行回归,测试用例需要平时不断的维护、根据业务变化不停的迭代,才能保证回归的准确性;同时,测试回归也是与测试同学进行对焦,从不同的视角上去发现问题,这也是集团要求发布变更前必须经历的一个阶段。
- 严格审批:审批本身也是起到一个“知会”的作用,例如在大促期,紧急变更需要审批到大队长,也就是这个意思,老板和横向PM具有更广阔的视角,需要让他们判断变更的风险性以及当前是否有必要进行变更。
- 卡点 & 灰度:上述的每个阶段,都必须通过产品化进行卡点,如果不通过则不能发布。
每个应用根据自己不同的情况都会有不同的卡点,不同的应用可能有自己的卡点平台,这些也可以通过对接Aone集成进去;至于灰度发布,大家都很熟悉了,这里就不展开讨论了。
✪ 2.1.4 混沌工程
建立完自认为完美的防线之后,肯定需要校验可用率,但是总不能通过等着线上出问题来检验防线是否生效,这样成本就太高了,此时就需要引入混沌工程,相信大家应该都很了解混沌工程了,那么就在这里贴一下相关的定义:
混沌工程,是一种提高技术架构弹性能力的复杂技术手段。Chaos工程经过实验可以确保系统的可用性。混沌工程旨在将故障扼杀在襁褓之中,也就是在故障造成中断之前将它们识别出来。通过主动制造故障,测试系统在各种压力下的行为,识别并修复故障问题,避免造成严重后果。
混沌工程在阿里集团内部的体现为故障演练,基本不需要部门内部自行操作,比较出名的有每年集团都会举办的红蓝演练,以及日常经常发生的生产突袭、断网演练等。
故障注入的平台,演练时一般使用集团内部比较出名的MonkeyKing,具体的使用方法这里不表,市面上有很多开源的混沌工程平台,原理都是类似的。
⍟ 问题分类
针对不同种类的问题,有不同的注入和恢复机制 ,不详细展开了,上一张分类比较好的大图:
⍟ 演练机制
整个故障演练机制分为四个部分,基本上也是所有混沌工程的思路:
准备:可以在这一阶段做一些故障演练前的准备工作,保障我们的系统以及监控在故障演练之前是处于一个稳定的状态,比如说在执行演练前自动检查一下机器的状态,应用的状态,甚至说故障演练的agent是否已经部署到了对应的机器上等等。
执行:在执行阶段可以选择你需要的故障场景,mk2里面支持像不同的应用注入故障,也支持同时像一个目标机器下发多个故障,故障的场景也不局限于mk平台提供的故障能力,用户自己开发的故障能力也可以集成进来。
验证:检查阶段就是进行故障执行后的一些状态检查,检查的范围包括了系统本身的一些指标,比如我是CPU满载,那么CPU是否真的满载了。
恢复:我们希望每个故障场景都是可以有相应的恢复手段的,如果故障注入后,开发人员没有办法在一定时间内处理故障,那么平台本身一定要保障故障是可以恢复的。
2.2 快恢机制
即使防线建设做的再好,但是人难免会有疏漏,不存在能百分之百拦截故障的防线,如果故障已经发生,那么当前的重点就应该是快速止损并恢复。
从发现、处理到复盘,阿里集团有一套完整的SOP,整个处理流程非常的规范,同时,阿里集团对于高可用故障恢复的时间要求非常高,一般来说是1-5-10,即一分钟发现,五分钟止血,十分钟恢复,不过肯定不是所有的故障都能严格达到这个高标准,但是处理速度当然是越快越好,避免故障升级。
那么下面就从定位、止血、恢复这三个阶段来讲述一下快恢中具体要做的事情: