You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

136 lines
15 KiB
Markdown

2 years ago
# 06 | 故障发现如何建设On-Call机制
你好,我是赵成,从今天开始,我们进入课程实践篇的内容。
在上一部分我们学习了SRE的基础需要掌握的重点是SLI和SLO以及Error Budget错误预算策略。SLI是我们选择的衡量系统稳定性的指标SLO是每个指标对应的目标而我们又经常把SLO转化为错误预算因为错误预算的形式更加直观。转化后我们要做的稳定性提升和保障工作其实就是想办法不要把错误预算消耗完或者不能把错误预算快速大量地消耗掉。
这么说,主要是针对两种情况:一种是我们制定的错误预算在周期还没有结束之前就消耗完了,这肯定就意味着稳定性目标达不成了;另一种情况是错误预算在单次问题中被消耗过多,这时候我们也要把这样的问题定性为故障。
今天,我们就来聊一聊,为了最大程度地避免错误预算被消耗,当我们定义一个问题为故障时,我们应该采取什么措施。
## 聚焦MTTR故障处理的关键环节
好了我们先回顾下在第1讲的时候提到故障处理的环节就是MTTR它又细分为4个指标MTTI、MTTK、MTTF和MTTV之所以分组分块也是为了更加有目的性地做到系统稳定性。
![](https://static001.geekbang.org/resource/image/3d/dd/3dd910e354da003e234b0340b68e76dd.jpg)
那么这四个环节在我们故障处理MTTR又各自占多长时间呢下面这个MTTR的时长分布图是IBM在做了大量的统计分析之后给出的。
![](https://static001.geekbang.org/resource/image/e5/fd/e5b28b0bed414afe8feda4f67b21a6fd.jpg)
我们可以看到MTTK部分也就是故障定位部分的时长占比最大。这一点我们应该都会有一些共鸣就是绝大部分的故障往往只要能定位出问题出在哪儿了一般都可以快速地解决故障慢就慢在不知道问题出在哪儿所以说我们大部分时间都花在寻找问题上了。
不过从我实际分析的情况看很多时候MTTR的时间分布跟这个图会有一些差别为什么呢
因为上面这张图是IBM针对网络设施的故障统计出来的鉴于网络设备部署模式相对简单以及日志和报错信息比较固定和明确所以出现问题时MTTI的判定阶段不会花太多时间。而且真的出现问题基本上采取的策略一般也是定位到根因再采取措施处理故障除了主备切换等冗余措施基本是没有太多其它手段。
但是在一个分布式的软件系统下我们判定一个问题发生在哪儿影响范围到底是怎么样的要召集哪些人共同参与定位排查等等这个反而会消耗更多时间所以我们看到MTTI阶段占比会更重。
另外当一个分布式系统发生故障时我们的策略一定不是找到根因而是优先恢复业务。所以我们往往是通过故障隔离的方式先快速恢复业务也就是我们经常听到的Design for Failure这样的策略再具体一点就是服务限流、降级、熔断甚至是主备切换这样的手段这样的话MTTK的占比会有所下降。
因此从分布式系统的实际情况来看整个MTTR的时间占比分布大致是这样的
![](https://static001.geekbang.org/resource/image/8e/ac/8e55074c8ec8e2c741ebeac7f7ae80ac.jpg)
其实不管是不是分布式系统我们针对处理故障的目的都是比较明确的就是要提升每个环节的处理效率缩短它们的处理时间这样才会缩短整个MTTR减少对不可用时长的消耗。
今天我们就先来看MTTR的第一个环节MTTI。看看在MTTI这个环节我们可以采取哪些措施来提高处理故障效率。关于MTTR中的另外三个环节也就是MTTK、MTTF和MTTV我们会在后面的课程中继续讨论。
## MTTI从发现故障到响应故障
MTTI就是故障的平均确认时间也就是从故障实际发生时间点到触发采取实际行动去定位前的这段时间。
这个环节其实主要有两件事情要做:**第一件事,判断出现的问题是不是故障;第二件事,确定由谁来响应和召集**。我们一一来看。
先看第一件事。我们平时遇到的问题很多,但是这些问题的影响不见得都很严重,或者都需要我们立即做出响应去处理。即便是故障,我们也会分不同的响应级别去处理。那我们怎么判断出现的问题是不是故障呢?如果是故障,我们应该以哪种级别去响应呢?
解决方案很明确,就是利用我们在[《04 | 错误预算:达成稳定性目标的共识机制》](https://time.geekbang.org/column/article/215649)中讲过的根据错误预算制定故障等级的方式来判定响应方式。我们把trade\_cart购物车的案例再拿出来你可以再看下作为参考。
![](https://static001.geekbang.org/resource/image/cc/c6/cc0987ffd5d5d9391bc58eb505c6ecc6.jpg)
在没有SLO和错误预算这个体系时我们通常会根据用户投诉或客服对同一问题的重复反馈来判断。比如10分钟内有超过50个用户投诉无法购买商品、支付不成功或者优惠券未生效等问题我们就会启动应急响应。不过一旦等用户和客服反馈就说明故障影响已经非常恶劣了用户也已经处于无法忍受的状态了。
显然这种方式并不高效。既然我们已经搭建了SRE体系设定了SLO能对稳定性进行量化管理那我们就能比用户更快发现问题并响应问题了。至于用户投诉和客服反馈的渠道只能是作为我们的辅助手段。
所以我们可以根据设定的SLO和错误预算准确判断发生的问题是否是故障并依据故障等级决定我们采取什么样的措施去处理这些问题大大提高反应效率。
接着来看第二件事,谁来响应和召集。这件事很容易理解,如果我们判定这个问题就是一个故障,首先要有人能判定,接下来需要哪些人来介入,并能够把相关的人员召集起来,一起来处理故障。
这两件事其实就是SRE里面提到的**On-Call机制**。
我们可以看到第一件事其实主要依赖于我们的监控和告警体系。这里我想再强调一下在On-Call阶段并不是所有的告警我们都要响应如果不影响稳定性一般的告警是可以降低响应级别的我们只需要响应基于SLO的告警。
我和很多公司交流过发现大家都非常重视监控体系的建设监控指标梳理得也非常全面而且各种监控技术和产品都会使用。比如从最早的Zabbix以及日志系统栈ELK再到近两年随着Kubernetes而火爆起来的Prometheus等等从技术上来说这一点不是太大的问题。但是第二件事往往容易被我们忽视也就是On-Call的流程机制建设。
## 关于On-Call的两个案例
在正式讲流程机制之前我先分享两个关于On-Call的案例。
第一个案例是发生在我自己团队里的当时遇到一次大数据产品HBase故障。那是一个周六的下午负责数据平台的运维同学收到了故障告警出现了部分节点不可用同时依赖该产品的搜索和推荐等业务也开始反馈异常进而影响到广告曝光导致资金损失。
问题出现后我们很快明确了故障的严重程度开始联系对应的负责人上线一起处理。因为是周末所以需要一个个打电话联系同时我们的HBase已经上云所以处理过程又需要云产品的同事介入这就又涉及到跨组织的协调。云产品内部又有分工一线服务、二线产品研发支持所以这个协调过程又是一个比较长的链条。再加上其他的权限问题所以等相关人员就位开始真正排查问题的时候距离发生故障已经有很长一段时间了。
当时我大致统计了下仅仅协调人员到位并上线开始处理问题这个过程就花去了45分钟而真正解决问题的环节只用了15分钟。
第二个例子是国内第一大企业IM产品。因为产品本身的特点每天早上八点半到九点会有一波使用高峰产品经常在这个时间段出故障。同时呢这个时间段正好是互联网公司通勤时间大部分技术员工都在上班的路上根本没办法处理问题导致故障时间过长。
所以为了保证及时响应,企业决定分批上下班,一批人早上在家值守,甚至是守在电脑旁随时应急,其他员工准时上班。等过了产品使用高峰期,值守的员工再陆续从家里出发上班。同时,下班也错开时间,保证有人可以及时响应。
这种错时保障机制,很多电商企业在大促保障或者重大活动期间也经常用,就是**确保关键角色必须在线,随时应急响应**。
通过以上两个案例我们发现从整体上讲如果要缩短MTTI时长技术相关的监控告警很重要但更关键的是一整套协作机制。这也是为什么像Google这样技术体系已经如此完善的公司还要强调On-Call机制的重要性。
那么我们怎样才能建设好On-Call 的流程机制呢?
## On-Call的流程机制建设
接下来,我就跟你说说,在蘑菇街我们是怎么做的,我把这个流程总结为“**On-Call关键5步法**”。
1.**确保关键角色在线。**
这里的关键角色不是指一两个值班的运维或SRE人员而是整个产品体系中的所有关键角色。比如电商就需要安排核心业务应用如用户、商品、交易、优惠及支付等的Owner或Backup中至少有一人参与On-Call轮班。不过接收故障告警或第一时间响应故障的一般是运维、PE或SRE这样的角色业务开发同事要确保及时响应SRE发起的故障应急。
2.**组织War Room应急组织。**
我们有专门处理故障的“消防群”暗含着灭火的意思会将这些关键角色纳入其中当有故障发生时会第一时间在消防群通报这时对应的On-Call同事就要第一时间最高优先级响应呼叫Page。如果是工作日对于严重故障会立刻组织成立War Room责任人会马上聚到一起如果是非工作时间则会通过电话会议的方式拉起虚拟War Room。
3.**建立合理的呼叫方式。**
在On-Call的落地过程中我们经常会遇到的一种情况就是谁最熟悉某个系统谁就最容易被7\*24小时打扰。比如系统或应用的Owner或者是架构师出现问题的时候一定是找这些同事处理的效率最高所以就会造成这些同事被默认为On-Call。
但是这样做会极大地影响这些同事在正常业务开发上的精力投入。他们要么总是被打断,要么就是经常通宵处理问题,导致第二天无法正常工作,甚至在非工作日也得不到正常的休息。
这种情况下我们建议使用固定的On-Call手机建立手机与所有On-Call系统的对应关系比如这个手机号码对应交易核心应用另一个号码对应IDC机房运维等等。这样我们在On-Call时就不再找具体的哪个人而是手机在谁手中谁就承担On-Call职责。除非问题迟迟得不到解决或者遇到了疑难杂症这种时候再呼叫其他同事参与进来。
无论是SRE、架构师还是一线开发**熟悉某个系统的最快最好的方式就是参与On-Call而不是看架构图和代码。**所以有效的On-Call机制可以让团队更深刻地认识到目前系统的存在哪些问题对自己的痛苦状态也会有更深刻的感受进而对后面的改进措施才能更有针对性和落地性。同时On-Call也可以培养和锻炼新人和Backup角色这也是让新人尽快融入团队和承担责任的最好的方式。
4.**确保资源投入的升级机制。**
这个跟前面几条有相关性有很多团队认为On-Call就是设置几个人值班所有的事情都交给这几个人做最极端的还会认为所有的事情都应该是冲在最前线的运维或SRE来完成。但是在分布式架构这种复杂场景下这种思路是明显不可行的。
这里最核心的一点就是要给到运维和SRE授权当他发现问题不是自己或现有On-Call人员能解决的时候他有权调动其他必要资源投入。如果故障等级偏高一下无法明确具体找哪些人员投入的时候SRE或运维可以直接上升到自己的主管或相关主管那里要求上级主管协调资源投入。必要时还可以上升到更高级主管甚至CTO或技术VP来关注。所以授权非常关键这一点的具体操作层面我们会在后面的故障处理过程中再详细介绍。
5.**与云厂商联合的On-Call。**
现在企业上云是大势所趋,绝大多数情况下,我们对问题和故障的处理,是离不开与云产品工程师一起高效联动的。所以,我们应该把云产品和云厂商作为我们系统的一部分,而不是单纯的第三方。而对于云厂商来说,也要考虑把客户业务作为自身业务的一部分,只有这样双方才能紧密合作。我们应该提前做好与云厂商之间的协作磨合,联合故障演练,必要的授权等等。
## 总结
最后,我们做一下简单的总结。
我们按照MTTR的细化分段可以看到处理故障的第一个环节就是MTTI也就是故障发现阶段。这个阶段我们要靠基于SLO的告警更加精准地告知我们当前系统的稳定性出现的问题并根据对SLO的影响程度也就是错误预算的消耗情况作出判断是否定性成故障。如果是故障我们就要启动应急响应而高效快速的应急响应是要靠On-Call的流程机制来保证的。
关于建设On-Call的流程机制我给你分享了我自己团队的“On-Call关键5步法”咱们再一起复习一下
1. 确保关键角色在线;
2. 组织War Room应急组织
3. 建立合理的呼叫方式;
4. 确保资源投入的升级机制;
5. 与云的联合On-Call。
当我们能够很好地做到以上两点的时候我们就能大幅降低MTTI也为接下来更高效的故障定位和恢复打下了坚实的基础。
## 思考题
最后,给你留一个思考题。
学完本节课的内容后你觉得在故障处理中是优先建设监控体系更重要还是建设高效的On-Call机制更重要它们两者应该怎么来结合会更有效欢迎你在留言区分享你的思考。
如果你在On-Call方面也积累了一些经验请分享在留言区也欢迎你把今天的内容分享给身边的朋友。
我是赵成,我们下节课见。