Oncall 心态指南:Dropbox 与 AWS 顶尖工程师如何看待事故应对与复盘

Oncall 心态指南:Dropbox 与 AWS 顶尖工程师如何看待事故应对与复盘

在前一篇 Pager 没响却听见警报?Oncall 工程师的睡眠与焦虑指南 里,我主要谈的是 oncall 的代价和如何防御。这一篇想换个角度,聊的是心态。

我最近听了两个访谈,一个是前 Dropbox 最资深工程师 James Cowling,另一个是 AWS Distinguished Engineer Marc Brooker。两篇访谈都很有启发性,但最让我意外的是,他们对 oncall 和 incident response 的态度竟然很接近:他们并不排斥这件事,有些人甚至会主动争取这份工作。像 Marc Brooker 就是自己选择持续参与 on-call rotation 长达 15 年。

这也让我重新问自己一个问题:incident response 这件事,有没有可能本来就不该被我们本能地排斥?也许我一直把它看成纯粹的负担和威胁,却忽略了它的另一面:它是学习的快速通道,也是展现主动负责的机会。这篇就是我的阅读与反思笔记。

TL;DR:三个心态转换

如果只想先带走三件事,可以先记住这三个重点:

  • Oncall 是最好的学习场域之一:Marc Brooker 说,他关于分布式系统的大部分实战知识都来自 oncall 和阅读 postmortem。把每次 incident 当成系统真实行为的一手资料,而不是单纯的麻烦工作。
  • 区分救火和学习:反复关闭同一种 ticket,代表这类工作应该被自动化;不寻常的 incident 才是值得深入挖掘的金矿。
  • 用主动负责取代抱怨:James Cowling 的核心心态很简单,“没有别人,就是我们”。incident response 不是被动挨打,而是主动说一句:“我来把这个问题修掉。”
mindmap
  root(("Oncall 正向心态"))
    Oncall 是学习场 (Marc Brooker)
      实战知识来自 oncall
      看系统真实行为
      看客户真实用法
    区分两种工作
      重复 ticket 要自动化
      不寻常 incident 要深挖
      目标是理解,不只是关单
    Postmortem 的力量
      先真正搞懂发生了什么
      多层次地问为什么
      跨 incident 找模式
      把教训变成工具
    警惕英雄主义陷阱
      被 page 100 次看起来很强
      内部看像高度负责
      外部却是根因没修
    主动负责取代抱怨 (James Cowling)
      没有别人,就是我们
      高度负责不等于一个人全包
      先想要不要现在就修
      投入一项值得投入的目标

一、顶尖工程师为什么会主动靠近 oncall

访谈里主持人直接问 Marc Brooker:很多资深工程师会想办法谈判退出 oncall,因为它看起来是低杠杆、很多摩擦的工作。你为什么还愿意待了 15 年?

他的回答几乎颠覆了我原本的看法:

I would say that the majority of my in practice knowledge about how to build distributed systems has come from being on call and analyzing and deeply understanding these post mortems and COEs. - Marc Brooker

他的意思是:刚出社会的工程师通常有不错的 CS 基础、写代码能力和数学能力,但缺的是很接地气的知识,也就是系统实际上怎么运作、怎么坏掉,以及客户怎么用它,甚至怎么乱用它。Oncall 正是最直接获得这种知识的方式之一。

换句话说,oncall 不只是运维成本,它也是一条高带宽的学习通道。当你站在 incident 第一线时,你看到的是系统在真实压力下的行为,而不是设计文档里想象出来的样子。对想成长得更快的工程师来说,这反而是别人很难复制的优势。

二、区分“救火”和“学习”

不过 Marc 也说得很清楚,这并不是叫你去当无脑救火队。他把 oncall 工作分成两类:

  • 重复、可预期的 ticket:如果你一直在关同一张单,这就是 toil,应该被自动化。现在做自动化比以前容易得多,也强大得多,资深工程师不应该把时间都耗在这里。
  • 不寻常、意料之外的 incident:这才是值得深入研究的部分。Oncall 的目标之一,应该是理解系统里奇怪或非预期的行为,把学到的东西带回系统里,再向公司和更广泛的社区传播。

If you have folks in your teams who are on call and they’re just closing the same ticket over and over and over, well, that’s where you need to just build some automation. - Marc Brooker

这一区分对我很有启发。上一篇我谈的是减少噪音:如果一个轮班里真正需要处理的 incident 超过两个,alert 设计就该回头检讨。而这里更进一步:把省下来的注意力,投到那些真正值得理解的 incident 上。

Oncall 的价值不在于你关了多少单,而在于你理解了多少原本不懂的系统行为。

三、好的 postmortem 长什么样

Marc 估算他整个职业生涯读过大约 3000 到 4000 份业界 postmortem,以及 Amazon 内部的 COE (Correction of Errors)。他说,每一份就算只学到一点点,累积起来也会很可观。

那什么叫一份好的 postmortem?

第一层:先真正搞懂发生了什么。 不要先带着自己的假设去判断。

If you can’t understand what happened, well, that teaches you something about your logging and metrics and observability. - Marc Brooker

换句话说,如果你连 incident 本身都还原不出来,那这件事本身就在告诉你,你的 logging、metrics 或 observability 可能有缺口。

第二层:多层次地问为什么。 不能停在 proximal cause(表层近因):

  • 有一个 code bug。好,修掉,但不能停在这里。
  • 为什么测试或验证没有抓到?
  • 为什么我们的测试流程会长成这样?
  • 为什么当初会对系统行为做那个假设?

一份好的 postmortem,不只是修掉那一行代码,还会一路修到测试流程、团队流程,甚至组织流程。

第三层:跨 incident 找模式。 当你在多份 postmortem 里看到同一类问题反复出现,就该往上抽象:能不能把它做成一个 service、一个 library、一个 community of practice,或者直接用技术手段消掉“一整类”问题?Marc 提到 Aurora DSQL 的例子,他们在设计时大量回顾关系型数据库相关的 postmortem,刻意把常见故障模式设计掉,比如 client 暂停、断连,却长时间持有 transaction lock。

How do we turn all of these lessons into new services and into service improvements? - Marc Brooker

访谈里也提到 AWS 内部每周三的 COE 会议:跨团队 leader 一起读 postmortem、讨论学到什么、怎么把这些经验应用到全公司。Marc 认为这个机制几乎是 AWS 成功背后的核心因素之一,因为它迫使公司里最好的工程师把时间花在“深入理解系统为什么会这样运作”这件事上。

四、警惕“英雄主义”陷阱:感觉很好,其实是错的

这段对我这种容易把“我撑住了”当成“我很负责”的人特别重要。

Marc 观察到,postmortem 文化薄弱的团队通常会落入两种失败模式:

失败模式一:对 outcome 的关注不够。 团队不够在意这个产品到底有没有跑得好、客户到底有没有真的满意。这是文化和领导层的问题,因为它意味着团队没有设定正确的标准。

失败模式二:把运维英雄主义常态化。

We don’t need to fix these root causes because our on calls are superheroic and they’re going to stay up all night and they don’t mind being paged 100 times a week. - Marc Brooker

从内部看,这种文化很像高度负责:这些人超投入、超强、愿意熬夜硬扛,被 page 100 次也不抱怨,看起来全是好信号。但从外部看,真相却是:团队根本没有修根因,只是在把一群高度负责的人,丢进一个昂贵的 break-fix 循环里。

最危险的是,这种英雄主义会让整个团队的运作感觉“很好”。那种“我们很在乎客户、我们很拼”的感觉,会让人很难承认自己其实是在错误的层级上付出。真正该做的,是把这股能量转去做 postmortem、做根因分析、做更有策略性的改善。一旦打破这个循环,反而常常会多出很多时间,真正把产品做得更好。

半夜被叫醒还能撑住、被 page 100 次还引以为傲,不是值得骄傲的勋章,而是系统该被检讨的信号。个人韧性救不了结构性问题。

五、James Cowling:把抱怨换成“我来负责”

如果说 Marc Brooker 给了我“oncall 是学习场”的视角,那 James Cowling 给我的就是面对 incident 和系统问题时更底层的心态。

他回忆 Dropbox infra 团队只有七八个人的时候,有人从 Google 加入后说:“应该有人去做一个 logging framework,不然我没法做事。”James 的反应是:

Well, who is someone? Because it’s just us. It’s just us. We build it or we don’t build it. There’s no other idiots out there. We’re the idiots. - James Cowling

这种“没有别人,就是我们”的主动负责,也很适合用在 incident response 上。很多时候,我们会把事故处理当成被丢过来的负担,潜意识里还在等“应该有更适合的人来处理”。但很多时候,那个“应该要有人”就是刚接到 page 的你。

James 带团队时,曾经刻意在 oncall 和被 page 这件事上,把这种负责态度做给大家看:

Very specifically, with regards to on-call and people getting paged, I wanted people to have high ownership. I’d be the first one to respond to a page. I would always be writing up the reports, really falling over myself to show how I wanted people to be. But from their perspective, all they see is that the lead is just doing all these jobs. - James Cowling

他希望大家一有状况就快速接手,所以自己总是冲第一:第一个回 page、第一个写报告、第一个把 bug 接起来。结果却有点适得其反。别人看到的不是“那我也该跳上去”,而是“这大概就是 James 的工作”“也许他才懂怎么弄”。这也点出一个容易被忽略的地方:主动负责没办法靠一个人全包来示范。你越是把每通 page 都揽在自己身上,别人越容易把 incident response 视为某个特定人的事,而不是自己的事。

“这有什么意义?谁在乎?反正就是个大组织,我做什么都改不了。”

James 接着谈到一个更大的障碍:他看到太多 junior engineer 在大公司待久了之后,慢慢变得犬儒,觉得自己做什么都没有意义。这种无力感,正是让人把 oncall 和 incident response 一律看成“事不关己的负担”的来源。

James 给的反例,是回到他自己的亲身经验:

Some of the happiest times in my life have been dedicating myself to a cause, trying really hard, and trying to do the right thing. - James Cowling

他补充说,这听起来也许有点老派,但真的做得到,尤其是当你刻意靠近一群“就是想把事情做对”的人。如果你在大公司里被政治搞得很挫折,不如去找这样的团队,而不是跟着一起犬儒。

对他来说,这种心态不是天真,也不是妥协,而是工程的本质:不是去做一个复杂花俏、只适合写进升迁材料的东西,而是把那个真正能解决问题、最酷的东西做出来。

能支撑这种心态持续下去的,还有一个关键:把抱怨变成行动。James 描述自己在 Dropbox 早期几乎把全部心力都投入进去,甚至一开始一天工作 16 小时,虽然他并不建议这样做。久而久之,大家知道他是真的在乎,他也因此累积了足够的信任,敢在需要时直接表达意见。他说自己怕的不是丢工作,而是怕看着错误的决定被做出来。后来他带了很多 staff+ 工程师,常常听到有人抱怨“某个地方很没效率”“我们没有在做对的事”。他不会跟着一起抱怨,而是用一个很巧妙的反问,把问题重新框回“优先顺序”:

Do you think we should solve this problem right now? - James Cowling

如果应该解,就告诉我应该从哪个团队抽人、该停掉哪个产品。我来重新调度资源,我们现在就解。重点其实很简单:与其停在抱怨,不如把问题拉回“我们要不要现在解、要怎么解”。如果它真的重要,那就把它扛起来,投入时间把它做完;如果不重要,也要坦白承认此刻还有更该做的事,把注意力放回更值得的地方。

James 的结论是:真正能往上走的人,通常不是最会抱怨的人,而是那些愿意站出来说“我觉得这个方向不对、这里有更好的做法、我愿意负责把它推到底”的人。

如果把这套逻辑套用到 oncall,incident response 就不再只是被迫救火,而是一次“我来把问题修掉”的选择。当我把它从“被指派的威胁”改写成“我愿意把问题接起来处理”,那种被动的焦虑感就会少很多。

六、我们可以怎么调整自己的 oncall 心态

把这两篇访谈和上一篇关于结构与睡眠的观点放在一起,可以总结出几个我们重新定义 oncall 的方式:

  • 把每次 incident 当成一手教材:事后问自己“这次学到了什么原本不知道的系统行为?”把它写进个人 runbook 或笔记里。Oncall 真正的产出,不是关了多少 ticket,而是从 incident 里学到了多少东西。
  • 分流注意力:遇到重复性的 toil,先想能不能自动化;遇到没看过的怪事,允许自己慢下来深入理解。那才是高价值时间。
  • 写多层次的 postmortem:不要停在 code bug,继续追问测试流程、团队流程,甚至当初为什么会做那个假设。只要跨 incident 看到了模式,就提议把它做成工具。
  • 拒绝英雄主义:被 page 100 次不是荣誉。如果我发现自己总是在救同一把火,那就是该在 retrospective 上提出结构性修复的信号,而不是咬牙撑住的理由。
  • 用主动负责取代等待:接到 page 时,不要再等“应该会有更适合的人来处理”。提醒自己:就是我们,没有别人。incident response 不是别人丢给你的包袱,而是你主动把问题接起来、负责到底的选择。

结语

两位工程师的职业路线差很多,但谈到 oncall 时,他们的看法却意外接近。他们共同传递出的信息都很明确:oncall 并不是一件应该拼命闪掉的苦差事。Marc Brooker 愿意持续 oncall 15 年,是因为他把 incident 和 postmortem 当成累积系统知识最快的管道;James Cowling 的版本更朴素,就是那句“没有别人,就是我们”。

oncall 的代价当然是真的。焦虑、被打断的睡眠、随时待命的压力,上一篇也花了不少篇幅讨论怎么防御。只是把这两篇访谈摆在一起会发现,单纯排斥它并不会改变什么。更有帮助的方式,也许是换个角度看待这份工作,在每次 incident 里多理解一点原本不懂的系统行为,慢慢把它从一种被动负担,变成一次主动解决问题的机会。

参考资料

Eason Cao
Eason Cao Eason is an engineer working at FANNG and living in Europe. He was accredited as AWS Professional Solution Architect, AWS Professional DevOps Engineer and CNCF Certified Kubernetes Administrator. He started his Kubernetes journey in 2017 and enjoys solving real-world business problems.
comments powered by Disqus