#一分钟精华速览 #
怎么样做好故障复盘?是否只要把事故要定责到人就能解决问题?
这是很多企业/团队都要面对的问题,有着超10年系统稳定性保障经验的李道兵老师给我们分享了他的观点:
故障复盘的三大关键问题:
- 怎么有效降低故障的影响?
- 事故处理的流程和原则有哪些?
- 相关管理制度怎么设置比较合理?
故障复盘的四大注意项:
- 事故复盘不是给人定责的,要有系统思维将优化项实际落地才能推动系统优化;
- 事故报告的重点应该是事故提升项,监控、定位、根因、架构四个部分都必须涉及;
- 事故报告的价值不仅仅是记录复盘故障,集中管理起来是很好的培训资料,能避免新人入职后走弯路;
- 架构师review是整个事故报告价值最大化重要的一部分,可以横向帮助企业研发团队相互借鉴避坑。
道兵老师结合实践经验分享了许多干货,感兴趣的可以往下阅读完整内容。
很多人应该都有关注SpaceX,从MK1到SN12所有的飞行器都没有成功,那这个实验到底是失败了还是成功了呢?借用埃隆·马斯克话来说这是一次成功的失败,他们公司从这些失败中汲取的经验远比一次成功的飞行多的多。SpaceX 的成功,让我们看到如果能够系统地从失败中学习,我们的进化速度能有多快。今天就从下面几个方面来给大家分享一些我的经验心得:
- 怎么有效降低故障的影响?
- 事故处理的流程和原则有哪些?
- 相关管理制度怎么设置比较合理?
一、怎么有效降低故障的影响?
不同产品不同的系统它其实完全不一样,有的以产品功能、用户体验为护城河,像美团、支付宝这种,我不了解。从2010年到2020年我做了差不多十年的云,以稳定性和信任为护城河的系统,这一块我略懂一点,今天就想分享一下我这一块的经验。要做好云要有很重的资本投入,要有解决方案架构师团队,要有好的产品,再细分就是功能、成本和稳定性,今天就专注稳定性这块跟大家具体聊一聊。
1、确定高可用目标,然后拆分它
降低故障影响首先要明确你的高可用目标,再围绕目标去做具体的拆分和优化。提到稳定性就会想到可用性,可用性达到3个9每个季度有2小时的不可用时间,4个9每个季度有13分钟不可用时间,5个9每个季度就只有1.3分钟的不可用时间。今天讲的内容是为了帮助大家达成3个9和4个9 的,也是大部分企业当前的目标,想要冲击5个9的就要做自动化了,用机器代替人力,那就需要一个完全不同的设计了。
不可用时长最简单的计算公式是:不可用时长=90天/MTBF*MTTR。MTBF指的是两次故障之间的间隔时长,MTTR指的是单次故障从发生到恢复所花费的时间。要想缩减不可用时长,从公式上来看很简单,就是增大MTBF或者减少MTTR。
2、从不同角度去想,具体能做些什么
2.1 增大MTBF
想要增大MTBF,有3个方向是可以做的——
- 首先是开发过程的质量控制,这个很重要;
- 其次是压测规范,因为很多不可用都来自压力过大,压力过大导致系统直接爆了,所以压测需要规范起来;
- 最后是上线流程,很多故障都发生在上线的瞬间,因为上线就意味着变更,变更就是事故的一个常见来源,明确上线前如何进行灰度,问题怎么排查怎么回滚,这些上线流程做好了也能规避掉一些事故。
2.2 减少MTTR
单纯的增大MTBF一定是不够的,举个极端的例子,你已经一年连续4个季度不出故障,考核没事了,第五个季度来了个影响时长超5小时的大故障,你可能就直接被干掉了,所以减少MTTR也是必须要做的事情。
将MTTR分解来看,主要分成故障发现、故障诊断和修复止损3个阶段,那这3个阶段我们应该做些什么来降低这部分的时间呢?
1)故障发现阶段
针对这个部分你得先搞清楚你的故障是客户发现的还是你自己发现的,如果是客户发现的那这部分的时间就不可控了,能不能变成自己发现的,变成自己发现起码能减少一部分的时间,那自己发现的能不能通过一些手段来缩短发现时间也是一个点。
2)故障诊断阶段
发现问题之后,如何进行快速诊断是重点。如果完全依赖人工,当你知道故障发生、打开电脑进入系统排查可能你的不可用时长就已经超标了,所以系统的自检能力建设很重要。自检结果是否有汇总面板,能否快速缩小故障范围,能不能一键让系统自己跑一套标准的测试来告诉你问题出在哪里,这些都是可以优化的点。
3)修复/止损阶段
这个部分我首先要问你一个问题,针对故障你是否有对应的预案,预案是否有过演练是否可实施,有预案可以快速响应止损解决一部分的问题。那修复止损难道就是改bug吗,显然不是,因为改bug真的很慢,也许你从2个9冲击3个9还可以考虑采取这种方式,但当你要冲击更高的稳定性目标的时候,就要学会使用其他更高效的修复方式了,比如针对故障的模块进行快速降级。
如果遇到不得不修复的问题,那有几个要点可以来缩短这部分的时间:
- 值班制度:要求随时有一个人能够拿到电脑来操作解决问题;
- 双人互备制度:当一个模块只有一个人了解具体的逻辑,万一这个人不能及时支援就会出问题,所以在研发的时候就要考虑到这个,每个模块都起码有2个对整体理解透彻的人;
- 现场指挥制度:每次遇到大型事故现场都会非常混乱,所以这块的设计就显得很重要,也能有效缩减修复的时间。
二、事故处理的流程及原则有哪些?
大部分大型系统从上线到能够完全平稳地运行,都需要一个打磨过程,短则几个月长则需要几年。除了系统本身的差异,是否有利用好每一次事故来改进自己的系统也是一个重要的点。每次事故都会有事故报告和事故复盘的过程,如果不明晰这些流程的目的,那么就会流于形式,也丧失了通过事故来改进系统的机会。
作为架构师团队的负责人,根据以往的工作经验我设计出一套事故的处理流程:止损—定位—快速复盘—事故报告—架构师review—整改跟进,配套的还有一系列处理原则可以去指导我和我的团队更好地处理事故。
1、止损
1)止损永远是第一优先级
为什么要特意强调这个,因为所有的工程师都有很重的好奇心,在事故现场他们最想做的事情就是搞懂究竟发生了什么而不是优先恢复系统服务。如果你有提前准备预案,那么就严格按照预案执行即可。
2)在保证止损效果的同时尽可能的保留事故现场
这可以为后续的定位工作提供方便,可如果保留现场会影响止损,那么还是止损优先,之后再考虑如何通过改造系统来提升在止损时保留事故现场的能力。比如说搭建一个好的日志系统,将所有的异常请求都记录下来,这也能帮助我们后续去还原事故现场。
3)止损现场要有一个决策人
决策人需要快速判定如何止损,同时分工协调现场人员去达到止损的目的。现场最怕的状况就是只有两三个人忙的团团转,而其他人不知道自己该干什么,也不敢去做相关的决策。
4)止损现场保持沟通
最好的状况就是大家都在现场,那么一起快速搬进会议室面对面地沟通协作,如果不能做到这个,决策人应该立刻发起电话会议,保证大家的信息及时同步,增加远程协作的效率。
5) 及时通知客服团队
这一点很好懂,有问题不通知客服团队,对外沟通出现问题,客服团队一定会投诉过来。
以上这些止损的原则其实都是为了帮助你更好更快地完成止损的动作,止损之后再开始考虑后续的定位工作。
2、定位
1) 止损基本完成前不要花精力在定位上
止损基本完成前不要花精力在定位上,除非止损本身需要定位。如果说不进行定位止损就做不了了,那么应该立即派遣团队最优秀的人和最熟悉该模块的人一起专心定位。为什么要两个人来做这个事情,因为最熟悉的人很容易陷入自己的思维误区,认为自己做的就是对的,这时就需要另一个人来共同梳理,分析业务逻辑里面有没有可能出漏洞的地方。这时现场决策人就需要做一些分工,让大家去分头收集信息并观察异常状况,有什么信息都要及时汇总。
2)不要轻易中止定位
有时因为压力产生的故障,当流量高峰过去,故障也就消失了,这时不要轻易中止定位,避免未能发现问题根因或者因为巧合导致问题消失。
3) 定位相关信息要时时记录
这是我经常遇到的情况,很多定位人员定位结束了,但整个逻辑链条里面很多证据都没有保存好,虽然得出了定位结论,但过程证据并不充分。所以我会给他们提一个要求,在定位的过程中手边要开一份文档,最好能粘贴图片,随时把定位过程中的信息拷贝到文档里,方便后续查看。
4) 定位的结论可以是无法定位,但要给出后续改进意见
我经常会强调一个观点,定位的结论可以是无法定位,但一定要给出事故再次发生后如何定位的改进意见。有时候故障就是消失了,定位不到也是可能发生的,但在事故报告中要明确之后该怎么做,这样当再次遇到这个故障时才能快速精准地定位。
3、快速复盘
在定位完成之后我一般会进行快速复盘的动作,拉上两三个人开站立会议,一般由负责定位的人来主讲,讲清楚事故发生的逻辑,其他人来给出信息补充或者提出质疑。当无法排除合理怀疑时,就需要继续定位了,直到完全定位结束。当你的逻辑都理清楚了,就到了讨论事故提升项环节,这块后面我会再展开讲。负责人在这里还要做一件事情就是安排大家收集事故报告的必要信息,并安排人来撰写事故报告。
4、事故报告
事故报告并不是因为出了事故,你搞砸了,我要惩罚你去写书面文档,而是说这些内容很有价值,后续也会成为培训的资料。当新人进来,他可以通过这些事故报告去了解以前系统出过哪些问题,后续又是怎么解决的,所以事故报告的逻辑一定要完整。
根据我的经验,事故报告应该要包括事故影响、事故时间线、事故原因分析、事故提升项这几部分的内容。
1)事故影响
这部分一定要把对应的监控图给及时截取出来并保存下来,因为监控系统不会一直保留之前的数据,几个月或者一年之后可能数据就没有了。
2)事故时间线
事故的时间线记录很简单,要从事故的第一次上线开始讲,此外你不要去加逻辑,就是简单地把事故处理过程中每个时间点系统发生了什么变化,对应的人都干了什么做了哪些尝试这些东西梳理清楚。
3)事故原因分析
这里是需要把逻辑讲清楚的,你要多画示意图,通过示意图来清晰展现这个架构下导致故障的原因。这里有个很重要的点就是不能揣测事故的原因,要排除大量的合理怀疑。单讲清楚事故发生的逻辑是不够的,还要讲清楚为什么其他的合理怀疑是不成立的,避免大家花费大量的时间最后得出的是错误的结论,做了错误的优化。
4)事故提升项
这部分我要详细说说,这块我是有具体的标准要求的,监控、定位、根因、架构四个部分都必须要有,哪个部分经过分析确实没有提升项就写“无”。
- 监控:两个自检的方向,事故发生后你是否第一时间收到了监控告警,事故发生前有征兆,征兆的内容是否监控到了,如果这两个部分都OK那基本可以说监控部分没有问题。
- 定位:现有的定位流程是否通畅,有没有什么改进的点,比如说需要一些工具,或者说完善日志的全文检索能力、日志的格式化与可视化能力,以此来提升定位的效率。
- 根因:根因是整个事故报告里最简单的部分,什么原因导致的事故修复优化了哪些东西。额外要说的一点是一个系统必须有2层防御能力,只有这样才能放心,不用担心下一次会出现一样的问题。
- 架构:有些问题是需要通过更加宏观的变更来解决的,这部分要明确如何通过架构的变更来从根本上来消除事故的隐患。
5、架构师review
架构师review是整个事故报告价值最大化很重要的一部分。建议大型集团都将高等级的架构师汇集到一起组成架构师委员会,这不是一个名称荣誉,是需要他们来干实事的,其中一个部分工作就是定期开会review事故报告,大概2-3周一次。
review事故报告有几个点很重要:
- 督促大家产出的事故报告得合格,必须信息完整、根因分析透彻合理、提升项没有问题;
- 在各个团队间进行举一反三,对类似的风险点进行排查;
- 提供一个不同团队之间高等级的架构师的交流平台,互相学习;
6、整改跟进
每个事故报告的提升项要写明负责人和预期的完成时间,架构方面的提升项一般用时比较长也不太紧急,但是也要写明时间,然后由项目经理团队持续跟进每个提升项的落实情况。最怕的就是一些中等级别的事故,事故报告的提升项洋洋洒洒写了很多,但没有具体落地实施,等到下次出现一样的问题时才发现之前没有做整改。提升项当然也是可以放弃的,但必须要有充分的理由。
前面架构师review会议产生的一些结论也是需要单独立项跟进的,这些整改跟进都落实到位了,才能对系统的稳定性提升有实质性的帮助。
三、相关管理制度怎么设置比较合理?
云平台本身是一个很庞大的系统组织,前面说了很多标准化的处理流程以及相关的原则,但组织是个有机体,所以这里面还涉及人的管理,这就需要管理制度来做辅助了,这边分享几个要点。
1、不要给低等级事故设指标
大家都会给系统事故定等级,P0、P1、P2、P3,然后针对故障等级去设立不同的目标。我为什么说不要给低等级事故设指标,因为这个指标的设立容易让大家隐瞒低等级的事故。即使你的目标设置的很宽松,比如说这一个季度P2等级的事故不能超过10个,但只要设置了目标,下面的人就会想这个事故没有人发现那我就不上报了吧。这就会浪费一次通过故障去提升系统的机会。
2、事故报告不要追究人的责任
事故报告不要追究人的责任,因为你是在建设一个系统,事故报告的提升项就应该体现在代码上,或者体现在一些强有效的文档里,比如说预案文档、值班制度文档。
3、要培训鼓励大家写事故报告
大家都觉得自己脑子好,不愿意去动手写文档,这时候就需要通过培训去要求和锻炼伙伴们的事故报告输出能力,鼓励大家多写报告,描述清楚,了解它的价值。
4、事故报告要集中管理
事故报告的集中管理是为了方便后续的复用,它是很好的新人入职培训材料。我们在书写的过程中不会去强调具体的人的责任,读起来会更客观,新人在阅读这些报告时能够了解系统的逻辑框架,知道一些逻辑写法会产生问题,就能更好地回避这些。
四、一个小小的实践分享
跟大家分享一个之前我还在云公司的小故事,这个时间有点长了。
当时我们还没有大范围的去使用容器,在做一个小的上线动作时,在reload之后发现有一台机器完全不能用了。工程师当时非常的好奇问题出在哪里,想去做定位,我说咱们应该先把这台机器下线然后继续跑。后续我们要做定位的时候就发现非常的诡异,一大堆的数据没了,其实是一整个的目录都没了。我们看了这台机器的操作记录,跟旁边的其他机器并没有什么差别。当时我们的运维需要对多台机器做批量处理,他就找了一个能同时控制多台机器的terminal来做指令下发。运维的操作也很规范,先创建一个目录来进行相关操作,完成之后回到上级目录删除这个目录,结果就发现有台机器出问题了。
具体是什么问题呢?目录的名称是fobar,这个名称大家都很常用,很不幸的是这台问题机器里某个目录下有个叫fobar的文件,在创建目录的那一个环节其实就已经失败了,没有进入到这个新建的目录里面。但后续的很多操作又都成功了,所以返回上级目录删除时出现了问题,直接把原目录干掉了。这里fobar文件的追溯是很难的,你不知道什么时候做了这个操作,也没有相关的监控手段。
针对这个问题,我们后续的整改方式就是terminal一律不准再用了,转而使用ansible来控制机器,在其他部门分享这个故障案例的时候也是获得了一致的认同,不再使用terminal,因为不知道哪一天会出现故障,后来我们也逐步建立了ansible脚本库。当然现在已经进入docker时代了,这些内容已经没有意义了,但从某种角度来讲docker又是解决这个问题的一种新的架构。
五、写在最后
2年前我离开了京东云,其实是有很多想法没有去落地实现的,这边跟大家分享一下,希望能给大家更多的启发。
1、自动根因分析
当你拥有几万台机器几千个服务的时候,就不是有没有监控警报的问题了,你永远都会有警报。那么就会产生一个需求,怎么围绕事故现象去把相关的警报筛选出来,当时有个想法就是去做系统的逻辑自检模块。简单来说就是每个系统都要明确自己依赖哪几个模块,这几个模块对系统的影响具体是什么。
2、黄灯与自动修复
红灯是事故、绿灯是正常,黄灯是需要尽快修复的部分,黄灯往往是事故出现前的征兆,围绕黄灯来设计相关的自动运维体系,就能保证很多事故扼杀在发生前。
3、K8s+混沌测试冲击5个9
K8s是一个非常好的自动化运维平台,配合混沌测试的手段就可以打造一个非常稳健的系统。这个稳健并不是说我的系统没有任何的bug,而是面向所有可能出现的情况我都有对应的预案,并且这些预案都已经固化在我K8s的脚本里面,这样才有机会去冲击5个9。
讲师精彩直播回放:https://news.shulie.io/?p=5016