2020年6月6日第18卷第2期Google出版了两本关于SRE(站点可靠性工程)原则、最佳实践和实际应用的书。1,2然而,在处理生产事件时的火热时刻,团队的实际响应和调试方法往往与理想的最佳实践不同。
这篇文章涵盖了2019年Google工程师如何调试生产问题的研究结果,包括工程师在各种组合中使用的工具类型、高级策略和低级任务,以有效地进行调试。它检查了用于捕获数据的研究方法,总结了生产调查的常见工程过程,并分享了专家如何调试复杂分布式系统的示例。最后,本文对该研究的Google细节进行了扩展,以提供一些可以在您的组织中应用的实用策略。
随着这项研究的开始,它的重点是发展对调试过程的经验理解,总体目标是创建满足谷歌工程师需求的最佳产品解决方案。我们希望捕获工程师在调试时需要的数据、他们需要的时间、相关团队之间的沟通过程,以及成功的缓解类型。这个假设是,工程师在调试生产事件时试图回答的问题类型以及他们应用的缓解策略都存在共性。
为此,我们分析了过去一年的尸检结果,提取了缓解的时间、根本原因和相关的缓解措施。然后,我们选择了20个最近发生的事件进行定性的用户研究。这种方法使我们能够在真实环境中理解和评估工程师的流程和实践,并深入研究无法通过分析验尸文档趋势提取的用户行为和模式。
第一步是试图理解用户行为:在最高级别,Google的端到端调试体验是什么样的?这项研究分为以下几个阶段(在以下各节中展开):
·阶段0-定义划分事件响应者和事件类型人群的方法。
·阶段1-审核一系列谷歌实际事件的尸检文档。
·阶段2-对处理这些事件的急救人员进行深入的用户访谈。
·阶段3-绘制响应人员在这些事件中的行程图,详细说明常见模式、问题和采取的步骤。
对研究人群进行划分的初步方法旨在确保包括足够广泛的事件和受访者集合,我们可以从中获取一组全面的数据。
首先,事件响应者(或随叫者)被分成两个不同的组:SWES(软件工程师)和SRE(站点可靠性工程师),前者通常与产品团队一起工作,后者通常负责许多产品的可靠性。根据在谷歌的任期,这两个群体被进一步细分。我们在不同的用户群中发现了以下行为:
·SWE更有可能在调试工作流程的早期查阅日志,在调试工作流程中查找可能指示故障发生位置的错误。
·SRE依赖更通用的调试方法:由于SRE通常待命提供多项服务,因此它们根据其系统的已知特征应用常规方法进行调试。他们寻找跨服务运行状况指标的常见故障模式(例如,请求的错误和延迟),以隔离问题发生的位置,并且通常仅在他们仍然不确定最佳缓解策略时才深入日志。
·较新的工程师更有可能使用最近开发的工具,而拥有丰富经验(在谷歌运行复杂的分布式系统十年或更长时间)的工程师倾向于使用更多遗留工具。直觉上,这一发现是有道理的--人们倾向于使用他们最舒服的工具,特别是在紧急情况下。
我们还检查了以下各个维度的事件,并发现每个维度都有一些共同的模式:
·规模和复杂性。爆炸半径越大(即其位置、受影响的系统、受影响的用户行程的重要性等)。问题越多,问题就越复杂。
·响应团队的规模。随着更多的人参与调查,团队之间的沟通渠道越来越多,团队之间更紧密的协作和移交变得更加关键。
·根本原因。在线呼叫者可能会对映射到六个常见基本问题的症状做出响应:容量问题;代码更改;配置更改;依赖性问题(我的系统/服务所依赖的系统/服务出现故障);基础基础设施问题(网络或服务器故障);以及外部流量问题。我们的调查故意没有关注安全或数据正确性问题,因为它们超出了本工作重点讨论的工具的范围。
·检测。呼叫者通过基于可用性或性能问题的人或机器检测来了解问题。一些常见机制包括以下方面的警报:白盒指标;合成流量;SLO(服务级别目标)违规;以及用户检测到的问题。
一旦确定了不同类别的事件,我们就阅读了20个确定用于定性研究的事件的验尸报告,绘制了响应人员在每个案例中采取的步骤。这种方法使我们能够验证影响响应人员如何处理这些事件以及他们面临的挑战的共同因素。我们还可以确保选择进行深度分析的事件分布在各个维度上,如上所述。
谷歌有一种强烈的无可指责的事后处理文化。4团队通常会查看其失败的历史记录,以确保其服务继续可靠地运行。正因为如此,内部很容易获得验尸文档,并且是分析调试行为的宝贵资源。与这些尸检相关的详细聊天记录有助于形成对发生了什么、何时发生以及哪里出了问题的基本理解。然后,我们可以开始绘制调试过程的原型。未来的研究可以通过应用自然语言处理来进一步验证事件响应聊天中的响应模式,从而扩展这项工作。
为了完成这项研究,对这20例尸检中确定的急救人员进行了深入的访谈,以便填补尸检文件中的任何空白。这些数据源为我们映射的调试之旅增添了浓墨重彩的一笔,并浮现出一组构成整个调试过程的核心构建块。
这项研究使我们能够生成Google实际事件调查生命周期的快照。通过绘制每个响应者的旅程,然后聚合这些视图,我们提取了与调试相关的通用模式、工具和问题,这些模式、工具和问题几乎适用于每种类型的事件。图1是每个受访应答者所采取步骤的可视映射示例。
典型的规范调试过程由图2所示和本节描述的阶段和子过程组成。在用户调查问题时,通常会重复这些构建块,并且每个构建块可能以不连续的顺序发生,有时还会以循环的顺序发生。
在检测到缓解阶段,调查通常对时间敏感-特别是当问题影响最终用户体验时。在找出根本原因之前,上门拜访的人总是会尝试缓解问题或止血。在缓解之后,上门调用者和开发人员通常会对代码执行更深入的分析,并应用措施来防止类似情况再次发生。
上门呼叫者通过警报、客户上报或团队工程师的主动调查发现问题。一个常见的问题是:这个问题的严重性有多大?
呼叫者的目标是通过检查情况的爆炸半径(问题的严重性和影响)并确定是否需要升级(召集其他团队,通知内部和外部利益相关者)来快速评估情况。随着更多信息的传入,此阶段可能会在单个事件中多次发生。
常见问题包括:我应该升级吗?我是需要立即解决这个问题,还是可以等一下?这次停机是本地的、地区性的还是全球性的?如果停机是本地的或地区性的,它是否会成为全局停机(例如,金丝雀分析工具包含的部署可能不会触发全局停机,而现在正在您的系统中传播的部署所触发的死亡查询可能不会触发全局停机)?
来电者形成关于潜在问题的假设,并使用各种监测工具收集数据,以验证或反驳理论。然后,上门呼叫者尝试缓解或修复潜在问题。这一阶段通常会在单个事件中多次发生,因为呼叫者会收集数据来验证或反驳有关问题原因的任何假设。
常见问题包括:错误和延迟是否出现峰值?需求有变化吗?这项服务有多不健康?(这是错误警报,还是客户仍在遇到问题?)。有哪些有问题的依赖项?服务或依赖项中是否有生产更改?
上门拜访的人的目标是确定什么缓解措施可以解决这个问题。有时,缓解尝试可能会使问题变得更糟,或者对其依赖的服务之一造成不利的连锁反应。补救(或问题的完全解决)通常需要所有调试步骤中最长的时间。这一步骤可以并且经常在单个事件中多次发生。
常见的问题包括:应该采取什么缓解措施?您对这是适当的缓解措施有多大信心?这种缓解解决了问题吗?
随叫随到的人的目标是找出潜在的问题,以防止问题再次发生。此步骤通常发生在问题缓解之后,并且不再对时间敏感,并且可能涉及重大代码更改。应答者在这一阶段编写尸检文档。
常见问题包括:哪里出了问题?问题的根本原因是什么?如何使您的流程和系统更具弹性?
在整个过程中,事件响应者记录他们的调查结果,与团队成员一起进行调试,并根据需要在团队外部进行沟通。
在每一次访谈中,上门拜访的人都报告说,他们开始使用指示给定服务健康状况的时间序列指标,执行广度优先搜索,以确定系统的哪些组件出现故障。大多数接受采访的团队对以下项目进行了评估:
·RPC(Remote Procedure Call)延迟和错误指标(类似于源自开源GRPC库的指标)。
警报和实时控制面板都使用这些指标。On-Callers通常仅在确定组件损坏后才使用日志和跟踪,然后需要深入到特定问题。
一些受访者应用SRE最佳实践来调试复杂的分布式系统,有条不紊地消除了他们关于可能出错的理论,应用临时缓解措施来防止用户痛苦,最后,成功地解决了最初导致停机的问题并从根本上解决了问题。
许多其他响应人员遇到了意想不到的路障。一些响应者受到整个堆栈中同时发生的一组复杂更改的影响。因此,隔离实际问题并找出如何解决它是极具挑战性的。其他应答者提到了流程和意识问题:一些人没有完全理解他们的生产工具是如何工作的,或者没有完全理解应该采取的适当的标准行动过程。一些响应者最终无意中将糟糕的变化应用到生产中。
下面是一些(匿名)故事来说明成功的调试会话和有问题的调试会话。这些轶事旨在表明,即使拥有最有经验的工程师、伟大的技术和强大的工具,事情也可能-并且确实会-以意想不到的方式出错。
以下是一个成功调试会话的示例,其中SRE遵循最佳做法,并在不到20分钟的时间内缓解了服务关键型问题。
在开会时,SRE On-Caller收到一个页面,通知她前端服务器出现500服务器错误。当她最初查看服务健康仪表盘时,一场寻呼风暴开始了,她看到更多的警报被触发,错误浮出水面。她反应迅速,立即发现她的服务不健康。
然后,她确定问题的严重性,首先问自己有多少用户受到影响。在查看了几张错误率图表后,她确认有几个位置受到了这次停机的影响,她怀疑如果不立即解决,情况将会显著恶化。这条问题线被称为分诊循环,类似于医疗保健中使用的分诊流程(例如,急诊室根据紧急程度或服务类型对患者进行分类)。SRE需要确定警报是否为噪音,是否需要立即处理,以及是否将问题上报给其他团队和风险承担者。
现在她知道这是一个真实而相对严重的问题,SRE开始从她的团队中拉来其他人来帮助调查。她还建立了沟通渠道,通知可能受到影响的其他团队,并让他们知道她的团队正在处理停机问题。
然后,她将重点放在为最终用户暂时缓解问题上。她让一名队友确保流量不会被路由到任何不健康的位置,并配置负载平衡器以避免将流量发送到受影响的位置。目前,这一行动阻止了问题的传播,这让她可以自由地使用监测数据进行更深入的调查。
接下来,她问了一系列问题,帮助她缩小潜在原因的范围,并找出如何最好地永久缓解这个问题。她主要使用时间序列指标(例如,云监控指标3)来帮助快速回答以下问题:
·缩小调查范围:服务的哪些具体部分是不健康的?错误是来自前端还是来自后端?是否有&34;个数据切片有问题?数据中是否存在异常值?
·确定问题的严重程度并排除原因:图形的形状是阶跃(某些东西突然改变并保持不变)、尖峰(某些东西改变,然后停止)还是斜坡(正在逐步推出)?错误率上升的速度有多快?
·确定严重程度:爆炸半径是多少?(如果在全球范围内发生错误,这表示存在很可能会对最终用户产生影响的严重问题。)。
·排除潜在原因:问题是什么时候开始的?服务或其依赖项中的哪些生产事件与此问题相关?
一旦问题得到缓解,SRE就会深入日志和跟踪,确认新的代码行正在使有问题的区域中的作业崩溃。她决定回滚到服务的最后一个稳定版本,并验证当受影响的位置重新联机时问题是否已解决。
以下是Google On-Callers在调试时遇到意想不到的障碍的一个例子,应用最佳实践本可以减少缓解的时间。
呼叫者会收到一个页面,通知他服务的总体服务器端可用性SLO(服务级别目标)已从99.9%降至91%,并且特定的用户操作失败。他通过查看度量图开始他的调查,这些度量图确认(1)错误率何时开始增加;(2)错误主要由超时引起;以及(3)请求持续时间大约等于超时持续时间。然后,他将指标切片到前面标识的失败用户操作,检查相关的服务器错误和每秒查询数指标,并深入服务器日志以查找特定错误。到目前为止,他一直遵循常见的调试实践。
同时,另一个后端服务依赖项的在线调用者注意到该服务接近其配额限制,并怀疑这种情况可能会对调查产生影响。此On-Call尝试通过更改配置来分配一些配额,希望缓解问题。但是,由于配置推送工具中的误解,此更改意外地删除了一个位置的后端服务器,而不是添加配额,这会增加其他位置的错误率。此外,由于他认为这一更改是安全的,因此上门拜访的人没有像最佳实践建议的那样密切监控更新配置的推出,并且最初没有注意到通过移除该位置实际上降低了总容量的指标。此时,呼叫者通过执行包括完全不相关的更改的未经验证配置的全局推送来打破最佳实践-删除后端的操作应与添加容量分开。
在此过程中,第一个呼叫者深入查看日志,发现删除后端服务器时权限被拒绝的错误增加。他通过广度优先搜索多个支持后端并分析它们的聚合日志来做到这一点。在这里,他注意到当一台服务器被删除时,更多的请求会流向出现问题的服务器。只有在深入挖掘日志并打开许多工具之后,他才能将错误与依赖项中的配置更改联系起来。
更好的工具可以防止用户执行意想不到的更改。工具还可以帮助验证更改的实际效果。此外,更好的工具来支持监视系统更改的影响,本可以帮助呼叫者更早地得出这些结论。
然后,上门拜访的人会联系起来,分享他们的发现。连接后,第一个呼叫方回滚降低容量的配置推送,识别更改权限错误的后端依赖项,并与后端团队合作回滚不良更改。
如果您负责运行分布式服务,您可能会发现自己要处理的场景与我们采访的团队经历的场景相似。我们的研究表明,应用以下原则的团队通常能够更快地缓解服务问题。
您需要有SLO和/或指标,您可以根据需要发出警报并选择性地进行报告。这些应该准确地反映用户的痛苦,并允许按故障域进行切片。这些还应与具有明确后续步骤和指向最重要信息的链接的警报相关联。
一旦具备了SLO的前提条件和准确的监控,您需要能够快速确定用户疼痛的严重程度和总爆炸半径。您还应该知道如何根据问题的严重程度设置适当的沟通渠道。
记录一组对您的服务安全的缓解策略可以帮助在线呼叫者临时修复面向用户的IS。
.