今天的课程,我将与你分享与监控系统关联最多的故障管理系统的落地经验。

监控系统与故障管理系统是相互补充的:监控系统发送系统异常,而故障管理系统则汇聚收敛这些异常,通过事先的故障级别定义,以及监控系统反映出的异常情况,持续预估故障的级别。

在跟进异常的解决过程中,故障管理系统通过监控系统的实时反馈,确定故障是否正在解决;

故障解决后,项目干系人结合故障管理系统完成故障的最终复盘,并将故障过程中所积累的经验进行技术宣导,对漏洞也进行修复,并弥补监控系统的不足。

所以,你可以看出监控系统的价值体现与故障管理系统密不可分。相信通过本课时的学习,你一定会对故障如何管理、处理有了更深刻的认识。

故障定义

首先我们要认识到,应用服务的线上问题是不可避免的。如新功能上线后,服务不能按照规定的设计完成,那就是出现了线上问题;而当问题很严重,不能及时解决时,就上升成了故障。

可能你会问:用户问题不能通过监控系统反馈出来吗?答案是否定的。这就好比谚语“道高一尺魔高一丈”,监控系统的持续建设,永远是由故障推演出来的。所以会有这样一种现象:故障越多、数量越大,就越倒逼技术人员去总结、去发人深省,最终建设出更好的监控系统。

那什么样的问题,问题严重到什么程度才能称其为故障呢?

1.从“五维”进行故障定义

可以通过五维图去定性、定量地甄别问题的严重程度。

影响业务功能:比如在电商系统中,用户无法使用“购买”功能了,这就是已经影响到关键功能了。所以我们根据业务功能,评估出问题的重要程度。

影响人群:影响到哪些人群?这些人群的标签是什么?比如新用户、某个地区的用户等。

损失预估:根据日活或交易数据评出损失,从而警醒开发人员在设计方案,以及测试人员测试时,能增加相应资源。

影响时长:问题持续时间越长,需要投入的资源也就越多。

影响范围:通过监控系统的拓扑功能,确认影响范围,从而发现潜在服务集群的瓶颈。

根据维度对应的权重比例进行评分加权和后,我们对“问题”就得出了一个评分;当问题超过一个固定的分值后,就升级为故障;在故障确认后,又可以根据具体的分值也就是严重程度,划分故障级别。

2.故障分级与分类

故障的级别不同,故障处理流程也就不同。在故障管理建设初期,以及应用服务的能力未到达预设规模时,故障分级不应过多。

常见的资讯类或使用类问题,还是通过日常运营或工单去解决,这样的效率才最高。

故障管理建设是避免可能发生的严重问题无人跟进,但对已发生的故障也必须进行积累,杜绝再次发生。

所以在项目初期,可以使用评分定级方式对故障做相应归类。通过过去两年的积累,我将故障分为了四大类。你可以根据以下分类,快速识别故障类别:

切记:采用分数进行分级只是表象,分类后对故障进行反思,这才是故障管理的真实意义所在。如按照严重程度,从强到弱,将故障分为 A、B、C 三级:

A 级故障必须是重复发生的故障,或是需要对全员起到严重警示示范的作业;

B 级故障必须有“监控无法自发现”等指标,而各个应用服务统计下来的各个小分类,又具备问题“群居性”,这样便能集中、显现地反映出应用服务功能存在哪些薄弱环节,从而指导应用服务如何建立监控进行修复。

C 级故障应具备对全局警示的作用。

故障处理机制

问题怎么演化成故障上面我们已经学习了,那当故障发生时,我们有什么“套路”可以指导我们减少故障时长,降低故障级别吗?

我的经验是按照如下行动准则,去调动项目干系人,在故障现场将整体的行动力拧成一个方向,完成故障处理。这个行动准则就是:先恢复,后修复;先核心,后边缘。

前半句是指导止损方式的,在定位问题后高优先级是:确认按照回滚方案或是将应用服务的代码版本回归到上一版本就可以完成止损;如果不可以,再考虑打补丁进行修复;

后半句则是在资源有限的情况下,应该先止损核心业务,先将影响核心功能和核心业务的指标降下来,也就是降低故障级别;然后,再完成剩余边缘的修复。

行为准则虽短,但是在故障处理的各个阶段都发挥着重要的指导作用。

接下来,就对故障处理的三个关键点进行讲解。

1.故障确认

根据监控系统异常情况和验证,就可以初步确认故障是否已经发生。确认后,需要持续跟进故障的五个维度(如上表),进行故障级别的实时预估。

对于用户数量,可以根据 App 上的日活和持续时间的比值,算出受影响的用户数;

通过 7 层域名的异常 Hits 和故障持续时间的比值,可以评估出服务的现场的稳定程度;

通过监控系统的拓补图,可以确认故障的影响面积。

2.故障止损

接收到监控系统的报警后,我们要做的就是止损,通用的止损方案如下。

优先使用回滚方案进行回滚:根据当次变更的回滚方案,再根据问题最近的变更时间点,依次按照时间倒序进行回滚。

其次可使用重启服务:在故障发生一段时间后,没有自恢复的迹象,也无变更相关操作的话,这时可能就是程序内部错误导致的。可以尝试重启少部分异常节点,观察是否有由于一些特有场景(如内存泄漏等)造成的故障。

资源有限的情况下:由于线上多为服务集群,所以优先将资源倾斜至重要业务服务的止损上。

3.故障原因

很多时候,想根据故障现场去快速定位出原因,这样的做法是不现实的。因为故障现场只能呈现问题的表象;而且很多时候编码已经经过了层层把关,直到到达线上才暴露出来,这就说明了当前团队很可能无法在短时间内,就确定出故障的根本原因。

这时你可能会问了:怎么推进定位故障的原因呢?

首先,我们有一个公认的常识:就是绝大多数的故障都是由于变更所造成。所以转换思路,不必再花费大量精力,从表象去剖析问题原因;而是通过自身对应用服务的变更出发,找到故障的真正原因。

相关人员可以根据自己的角色,针对性地使用减法,排除是否是自身的“变更”引发了故障。

我将“变更”总结为以下四大类。

环境变更:随着业务体量的发展或缩减,避免不了对应用服务所部署的硬件环境进行调整,比如为了给应用服务更高的算力,将应用服务迁移到更高配置的机器上。我曾遇到过由于扩容节点,新节点使用的 JCE 环境导致代码调用 AES 加密方法失败。环境变更问题让 SRE 去完成原因定位是最合适的。不过解决问题很简单,将新节点流量摘掉即可止损。

代码变更:需求所导致的每次代码变更都要明确上一次稳定版本的版本号,若上线内容只包括代码变更,且变更后就发生问题,那项目组相关 RD 便可以执行“快速回滚”操作。

配置变更:一线开发为了应用服务有更好的灵活性,都会将一些判断的代码通过配置去实现。比如某些功能开放给哪些地区,通过配置中心如 Apollo,在变更配置导致故障发生时,可以使用“回滚配置”完成止损。

数据变更:数据变更的故障定位和修复,我认为是最难的。首先在重大变更时,我们会备份影响关键数据表。在变更后,数据变更往往伴随着代码变更,若出现线上问题,及时进行了回表等相关操作,还是会有脏数据产生。这时为了最保险起见,建议开发一些需求外的数据修复小工具,确保脏数据的修复。

综上所述,我们尽可能拆解变更,不要让一次发布包含多种类型变更。

原则上,我们所有变更都要有回滚流程和策略。

设计上,要考虑回滚后,新功能是否涉及上下游的兼容问题。如果不兼容,需要有多方共同的回滚方案。

小结和思考

今天的课程到这里就告一段落了,我们可以看出线上故障止损的过程就像救火一样,需要采用最直接、有效的手段减少损失。

故障管理系统在整个服务集群中,就像古代城邦中的“望火楼”的作用一样:

在故障发生时,可以及时收敛监控系统发来的报警信息,然后周知相关责任人;

然后,开始跟进相关干系人的修复过程;

止损后,再复盘整个过程,将故障暴露出的问题进行总结,以此确认应用服务集群中是否还存在同类问题;

最后,跟进全局的漏洞修复。

在故障管理系统对接监控系统后,可以让问题有快速地初步认定,并关联到初步干系人;汇聚收敛的最大意义,就是让专门的项目组可以持续将故障经验纳入、积累,让其成为公司的技术资产,并将这些资产转化为教程进行宣传,让开发、定位、提效走上正循环。

那么,你在工作中肯定也遇到过很多线上问题,对于如何快速修复问题,你有什么套路吗?欢迎在评论区写下你的思考,期待与你的讨论。

-– ### 精选评论