在线服务的稳定性保障一直是运维和技术部门的核心工作之一。但时至今日,这个方向实际仍然有很多基本的概念都没有对齐。今天这篇文章就罗列下那些混淆不清的概念,期望有一天大家沟通时不是鸡同鸭讲,各说各话。
听过很多技术分享,看过很多平台的承诺,上来都是讲我们的服务稳定性99.9xx%
,但似乎都“忘记”了提供这个稳定性的具体算法和解读。如果没有明确的定义,这个数值其实毫无意义。
服务稳定性目标的算法并没有行业标准,Google SRE Book 中提到两种:
可用性 = 系统正常运行时间 /(系统正常运行时间+停机时间)
可用性 = 成功请求数 / 总请求数
使用哪种统计算法很可能因业务的类型(电商服务、打车服务等)或服务的类型(请求类服务、存储类服务等)不同而不同,甚至因公司的传统和文化而不同。
而实际上,以上两种算法本身就存在很多不明确的地方。
如基于时间的可用性统计,哪部分时间适合算到停机时间里?服务还部分可用算不算?只影响了 10%的用户算不算?如果只统计完全停机的时间,那即使是非常严重的事故也可能统计不到停机时间里,这显然是不合理的。
而合计可用性也一样,通常这种方式都是在接入网关上对请求的日志做统计,但故障时很有可能出现:
这些因素都会导致统计上的错误,并且数据修正非常困难。
国内,各家公司的可用性统计方法五花八门,可能基于以上方法做了各种变形和补充,因此相互之间并没有可比性。各公司内部也只有在统计算法不变的情况下,和历史去对比才能看出价值。
所以,当提到服务可用性目标时,比较严谨的说法是:
我们的服务可用性从
99.xxx%
提高到了99.yyy%
,它的算法是什么,意味着什么什么。
什么样的异常算故障?笔者在做运维的早期第一次听到这个问题时,有种被击中了的感觉。因为我们天天大谈故障,甚至 KPI 里都有故障相关的任务,但都只是凭感觉,却没有对它做过定义和量化。
入口模块的一两个请求失败算不算故障? 1% 的请求失败算不算故障?到什么程度算故障?
故障,直观上大家的理解是比较严重的异常。只是一般的异常和严重的异常如果不加区分,可能会有几种后果:
完善的服务稳定性保障,建议对这些概念进行量化定义:事件、异常、故障、事故。笔者认为这几个概念的范围是从大到小,影响程序逐级递增的。
而且值得用一个专门的系统来对这些概念做量化和报警。这样,当大家提到“故障”时,或收到“故障”的报警时,它在大家脑子里的严重程度都是一个量级的。
什么是根本原因?
在过往的故障复盘经验中,我发现故障的直接原因、重要原因、触发原因、主要原因,这些原因都是相对能够确定并被接受的。但唯独根本原因,这个原因如果深究起来,并不太容易形成共识。并且这么沉重的一个词,很多团队潜意识里不太想承担这个原因对应的责任。
比如,一个新用户上线变更,没有好好检查导致了服务故障。这个事故很可能的直接原因是上线变更,触发原因是程序中的某个 bug ,重要原因是没有按要求做好变更检查。
但根本原因是什么?因为根本两个字就要寻根究底,假设从重要原因出发,这位同学没有按要求做好检查,那为什么他不按要求做检查?导师没有培训过?团队没有做好变更意识的培训?平台为什么没有做好变更的拦截?他自己一时大意,但针对这种重要的变更为什么没有 double check 机制?
如果继续深究,那根因最终会归因到笔者前公司的一个口号:一切责任都是管理者的责任!但任何故障的根因如果都是这个,那以后也就不必分析根因了,因为结论都一样。这也是为什么只要出现事故,管理者一般都会跟着被处罚的原因,因为他们的管理责任就是“根本原因”。
所以,如果提及这个原因,希望你们的公司或团队对他的定义和深究的程度已经是明确的。
故障处理中往往会提到这个概念。这个场景下大家自然不会像复盘时那样联想到去找管理上的、流程上的根因。但却有可能将一些人引导到错误的故障定位方向上去,比如,一开始就对个别报警前后分析,深入代码去寻找 bug ,或深陷在技术的追根溯源上。
这个做法对不对呢?在问题排查中是对的,但在故障处理场景中是不对的!
为什么呢?因为故障处理时的第一原则是止损,是尽快恢复服务的核心流程和核心体验。
要做到这一点我们应该寻找尽可能高效的方法。比如,多活服务中的一个单元异常了,这时候只要确认其它单元的服务正常,容量充足,做一个简单的流量调度即可完成止损,最多再锁定变更,这个故障处理的过程就结束了。再比如,服务故障时优先查看有没有核心模块的变更,如果有,尽快回滚,很可能服务就恢复了。
故障处理的过程其实是一个将故障整体的关键特征、关键事件去和一个有效预案连接的过程,是一个多团队协同的过程。把它叫做根因定位从表意上就不准确,而且隐含一种错误的引导:让处理人员在这个场景下优先去寻找 bug 、寻找异常在技术上的深层原因。上来就从前往后 trace 、debug ,最终可能也能解决问题,但应该是在首先分析全局的故障特征和关键事件后,发现没有有效的办法/预案再去做。
所以,故障处理中,不建议提根因定位,叫故障定位、故障定界、故障分析这类的词都会比“根因定位”产生的误导少。
运维或基础技术团队通常离真正的“业务方”比较远,最常打交道的是业务的研发团队,技术部门里业务研发团队是经常和“业务方”打交道的团队。因此在运维和基础技术团队看来,业务研发团队可能就被代表了“业务方”。
基于这个认定,通常在监控划分时会出现把业务研发团队提的需求或关心的指标归类为业务监控的情况,如错误日志、模块流量、接口延迟等。但实际上真正站在业务负责人或公司的角度,业务肯定不是指业务研发团队,业务研发团队只是直接支撑业务的团队之一,还有运营团队、产品团队、销售团队等等。
业务监控对应的指标,应该是业务负责人和这些团队共同关心的指标,甚至是运营、产品、销售这些团队更为关心的指标。这类指标包括类似 在线用户数、订单量、GMV 、在线商品量等。以及这类指标衍生的指标,如分地域、分人群、分时段、分渠道来观察的这些指标。
对了,你或许想到了,这些指标通常可能已经存在于公司的 BI 系统里,老板们用它们来观察分析业务的发展情况,运营们用它们来分析营销的效果。如果严格定义业务监控,应该是对这类指标做监控展示,并实时的报警,这才叫业务监控。
当然,在具体的指标采集上,有可能一个业务监控指标和其他监控指标是同一个指标,比如,一个关键模块的流量,或从模块日志中提取出来的特定流量可能就可以代表这个业务的订单量。
那如何区分一个监控到底是不是属于业务监控呢?我认为可以从以下几个方面来判断:
如果细分故障处理的过程,业务监控是发现故障的重要手段。但很多企业或业务要么没有业务监控,要么实际是把其它监控混杂在了“业务监控”的概念里,如应用/模块的监控,也没有明确这些监控应该面向的真正对象。这个做法的后果是业务监控得不到应有的重视,发挥不了应有的价值。
以上总结了服务稳定性保障中常被混淆误解的五个概念,可能还有更多的概念未被清晰的定义,希望以此为鉴,大家一起推动服务保障领域的标准化、量化和最佳实践。
后面还将谈谈稳定性保障中常见的错误做法,敬请期待,也欢迎交流探讨。
关于夜莺监控
夜莺监控是一款开源云原生监控分析系统,采用 All-In-One 的设计,集数据采集、可视化、监控告警、数据分析于一体,与云原生生态紧密集成,提供开箱即用的企业级监控分析和告警能力,已有众多企业选择将 Prometheus + AlertManager + Grafana 的组合方案升级为使用夜莺监控。夜莺监控,由滴滴开发和开源,并于 2022 年 5 月 11 日,捐赠予中国计算机学会开源发展委员会( CCF ODC ),为 CCF ODC 成立后接受捐赠的第一个开源项目。