池建强的公开课

讲讲咱互联网行业自己的故事

个人成长,观点,认知, 软技能

池建强 极客时间创始人、墨问西东创始人

第286期 | 如何从容地应对生产事故?

讲述:池建强 大小:9.04MB 时长:00:09:25
00:00
1.0×

你好,这里是卖桃者说,今天和你聊聊生产事故这个话题。

说到生产事故,我相信每个程序员都在工作中遇到过。有些是因为疏于维护,有些是因为判断失误,还有的是因为操作不当等等。我做程序员二十多年,见过各式各样的生产事故,有出安全问题被拖库的,还有删库跑路的,也有代码逻辑引起的,不一而足。

前几天我和我们的每日一课老师冯忠旗聊了这个话题,冯忠旗老师是京东数科高级架构师,也是《一个 1000 万资金重复支付的代码剖析》《如何快速设计出一套实用的监控系统?》等每日一课上热门课程的作者。

他回顾自己工作这些年所经历的各种各样的事故,从研发流程分析,有产品设计考虑不足产生的、有研发 bug 产生的、有运维操作导致的、也有运营配置导致的等等;从技术角度分析,有功能缺陷、有性能问题、有防重处理问题、有并发请求问题、也有幂等性问题等等。

这些事故中有些让人意想不到,有些是低级错误,有些还挺有趣。但也正应了那句话:幸福的家庭都是一样的,不幸的家庭各有各的不幸。

在冯忠旗老师看来,很多事故并不是偶然出现的,一定是各个关卡都没有拦截,才会导致最终出现错误。但凡有一个环节做了拦截处理,那么一定会拦截住这次事故。正如海恩法则所说:“每一起严重事故的背后,必然有 29 次轻微事故和 300 起未遂先兆以及 1000 起事故隐患。”

前阵子,我在 InfoQ 上看到一则真实的故事:一家世界排名前一百的养老基金公司,系统出现了一个极其严重的错误,直接影响到了公司业务。更糟糕的是,当年负责写这个程序的员工早在数十年前就从公司离职了,而且在 15 年前已经离开人世。核心开发者联系不上,他的代码也没人读得懂。虽然问题最后通过提供热修补脚本的方式解决了,但还是给公司造成了 170 万美元的直接损失。这个教训不可谓不大。

对于一个像这样数十年没有维护的系统来说,很多因素都可能会导致它出现灾难性的事故,比如源码丢失等等。因此,开发团队一定要做好预防工作,尤其是要做好事前预防。

关于预防,冯忠旗老师给了几点建议:首先,在日常工作中一定要建设好团队体系,重要项目是什么,重要岗位有哪些,必要时可以设置 AB 岗,消除单点,培养团队每个人员都能独当一面;其次,还要建立团队风险防范和事故预防/复盘规范流程,让每个开发人员都能时时刻刻有风险意识

如果真的遇到核心开发人员离职或失去联络,就要果断采取事后预防,确保新接手项目的人能够按照规范,从各个维度进行项目和代码梳理。

不过,很多时候,即便预防工作做得再到位,还是会出现生产事故。我觉得只要不是伤筋动骨的大问题,出些小错也是可以理解和接受的,毕竟很多问题你在事前是想不到的。没有经历过,没有经验,自然很难躲过这些坑。

出现生产事故并不可怕,可怕的是你处理不及时,或者处理方法不当,这会加剧生产事故影响范围,最终造成不可估量的损失。

之前,冯忠旗老师曾在每日一课上讲过《如何从容地应对生产事故?》,里面提到了处理事故的 7 个核心思想,这些核心思想可以帮助你高效地应对生产问题,非常有价值,接下来我就和你分享一下。

1.事故洞察

首先,你得对自己负责的系统了如指掌,同时有多种渠道来源,能够帮助你第一时间发现生产事故,比如实时监控预警系统、客诉部门、基础服务支撑部门、第三方服务依赖方等等。

如果核心业务交易量大、交易分布时间相对平均、业务面向 C 端用户多、业务重要程度高,需要特别安排 7*24 小时监控室+工程师轮值 on-call 机制,on-call 要求轮值工程师在一定时间内随叫随到,做好生产环境出现紧急情况的应对准备。

2.事故分析

如果确保了第一时间能够发现生产问题,接下来最重要的事情不是去定位问题发生的根本原因,而是要先去分析事故的影响范围和严重程度,比如是否会产生资损风险、资损的金额可能有多大、影响用户的范围有多大、是否非常严重等等。

为啥这么做呢?因为研发人员的特点是发现问题会习惯性地排查问题的原因,而且一般都会觉得自己可以快速解决掉问题。可往往真实情况是,一个技术难点陷进去之后需要很长时间,就算这个难点解决了,却发现又出现了第二个问题。这就像电视剧里面通过线索排查案情一样,问题一环套一环,结果是时间可能已经过去了 30 分钟,问题也没有解决,这个时候生产事故已经扩大影响范围。

3.事故升级

如果事故属于严重程度,需要立刻进行事故升级,通知相关业务方和上级领导。及时向上级汇报有三大好处:第一,领导会根据严重程度协调高层资源,进而加快解决问题的速度;第二,没有完美的生产事故解决方案,很多时候需要领导在不同方案中做决策;第三,就算这次事故没有处理好,第一时间告知领导之后,至少不失告知责任。

需要注意的是,在给领导汇报生产事故的同时,最好提供一些事先应对预案,并将不同预案的风险和优缺点如实告诉他,请他来决策和支持。

4.事故应对

如果你在长期的应用运维过程中不断积累和沉淀,那么,对于 80% 的常见问题你是可以提前做出应对的。比如,Java 系统产生 OOM 内存溢出,虽然不知道是什么原因导致的,但是可以通过立即重启来恢复服务;再比如数据库连接池占满,导致其他服务不可用,如果没有最好的方案,可以从数据库层面杀掉耗时最长的慢连接。

5.事故复盘

事故解决之后,需要做的事情是复盘事故发生和解决的详细过程,包括发生时间、参与人员、详细处理过程、结束时间等环节。如果事故的应对方案是短期临时方案,还需要进一步针对此次事故制定长期解决方案,并且快速上线。

复盘最主要的目的不是问责,而是回顾解决事故的整个过程,总结经验,下一次遇到类似问题能够更加快速从容地应对。此外还能通过复盘分析事故的特点,寻找能够提前避免的预防方案,因为最重要的事情还是需要做到事前预防,而不是事后补救。

6.完善方案池

这里所说的方案池更像是历史生产事故记录表,你可以把经常发生的事故的应对方案放到应急方案池中,作为团队的共享资源。一旦发生这类问题,就算是新入职的同事也可以参考方案池快速解决问题。

如果再有新的事故发生,就再次把新的方案融入到方案池,这样方案池就越来越丰富,从而不断积累形成宝贵的经验。通过这种方式,生产系统的新问题一定会越来越少。

7.故障演练

研发团队需要不定期做故障演练,包括数据库故障演练、应用故障演练、网络故障演练等一系列的极端情况下的故障模拟,确保真正出现问题的时候,能够沉着应对。

当你掌握了这些方法,就能从容地应对生产事故,避免或者减少生产事故所带来的影响。

最后做个小调查,你遇到过的最让你印象深刻的生产事故是什么?你从那次事故中有什么收获吗?对了,我还为你申请了每日一课的优惠口令,具体使用方式参见文稿。

  • 口令:meiriyike
  • 适用:每日一课月卡、季卡、年卡
  • 使用规则:立减 10 元(满 40 元可用)
  • 有效期:6 月 8 日 00:00 - 6 月 14 日 24:00

卖桃者说,明天见。

(编辑:夏天)