找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

1464

积分

0

好友

216

主题
发表于 5 小时前 | 查看: 1| 回复: 0

处理完几个SEV(严重事件),在从北京返程的航班上,Google Photos 推送了一条回忆:“十年前的今天:波多黎各的海”。那是我在Google期间出差拍摄的。照片没看几秒,脑海中浮现的却是那次出差归来立刻触发的一场重大故障。

无独有偶,后来在蚂蚁集团,某年12月初出差,临走时也硬生生被一个故障留在了杭州。仿佛职业生涯中只要遇到出差,总能撞上或大或小的问题。这不禁让人怀疑,难道我的体质天生不适合离开工位五百米?

十年前的那次出差旨在加强美国与欧洲两地SRE团队的交流。回来的第一天,时差还没倒过来,半夜就第一次被page(告警呼叫)惊醒。当时还有些诧异,毕竟两地轮流值班,美区的SRE按理不太可能在这个时间接到电话。

第二天一早,我迷迷糊糊踏进作战室(war room),所有人表情严肃,鸦雀无声。当时的我还是个新人,只能搬把椅子坐在角落了解上下文。会议室的大屏幕上,Ben Treynor(Google SRE的奠基人)硕大的头像占据了半个屏幕,那场景比监控面板全线飘红更令人紧张,大概如下图所示:

图片

印象中那是内部鉴权体系的一次雪崩,具体根因已记不太清,只记得是一个刚入职不久的同事所做的某次变更引发。这场故障的内部代号OMG/1354被我们念叨了很多年,以至于后来某年的同一天,我们还认真地买了个小蛋糕,给那位同事过了个“故障纪念日”。

故障的公开信息或许能通过搜索“Google App Engine Incident #15025”找到。不过在2025年再打出GAE这个词,多少有些感慨时光飞逝。后来我们团队对整个鉴权体系进行了拆分和重构:一方面,花了三年时间从Java迁移到C++;另一方面,将用户账户体系与GCP的Service Account彻底分离。以至于我现在每次在K8s里敲ServiceAccount时,都会下意识地停顿一下。转念一想,如果这件事发生在今天,对GCP的影响可能会被放大数倍,当然,也有可能变更引入的错误代码能在code review时被类似Gemini这样的AI代码助手发现。

类似的剧情总在反复上演。只要一家企业还依赖云服务或各类SaaS,每年年底就需格外警惕:各方都在冲刺OKR,云厂商、SaaS提供商、内部团队皆是如此。越是号称“年底冻结变更”,越容易在“这也不算变更吧”的灰色地带里,接连翻车。

所以,基于这个假设,出差或许只是强化了墨菲定律:当你不在时,系统会用自己的方式提醒你,你本就无法完全掌控所谓的稳定性。

稳定性的方法论

这些年我有一个越发强烈的感受:稳定性治理谈不上什么万能方法论,在复杂的分布式系统与人心之间,很难存在放之四海而皆准的金科玉律。PPT中所谓的“稳定性治理体系”,本质上是一套人类与系统讨价还价的规则。你以为制定了流程、设定了SLO(服务水平目标)、建立了值班表,就能在这场交易中多换来一点确定性。但系统总会用下一次变更告诉你,这些条条框框,究竟是你手中可兑现的筹码,还是只写在PPT里好看的价目表。

非要说共识,大概就是绝大多数故障都与变更有关,80%也好,90%也罢,差别只在于统计是否严谨。如果按场景粗略划分,我遇到过的麻烦主要有以下几种。

一种是缺乏有效的测试环境,或者根本不知道该测什么,索性直接拿生产环境当测试。2019年SREcon大会上还有人专门分享过如何“在生产中测试(test in production)”,当时听着也很令人心动。但那套理论建立在极其完善的测试体系、灰度发布体系和可观测性基础设施之上,再加上特定的业务形态。对于大多数团队而言,“在生产中测试”更像是一句不负责任的话:“让用户帮你测”。

另一种是一团乱麻般的变更影响面分析。尤其是基础设施的变更,往往与上游业务脱节:修改一段安全组规则、升级一个中间件版本、调整一下限流参数,看似问题不大,但真正的爆炸半径,常常会穿透好几层架构,最终落在一个谁都没想到的业务应用上。大概没人能画出一张完整的“影响面地图”。变更评估做到最后,多数时候只是把能想到的风险圈出来,剩下那大片空白,就交给了那句“感觉没问题”。

还有一种,则是依赖关系模糊的开源组件或中途接手的遗留系统,基本没人能说清其上下游关联。很多系统是临时接手:代码不熟,文档缺失,依赖关系只存在于某位已离职同事的记忆中。这时修改配置,如同盲人摸象,你以为调整的是象鼻,结果可能扼住了生产环境唯一一台数据库的脖子。

既然要控制变更,第一反应往往是增加审批环节。但绝大多数审批缺乏实质的技术意义。尤其是当审批人已脱离一线,而变更内容又复杂到无法在一行说明里解释清楚时,指望一位远离生产日志的管理者来做技术兜底审批,多少有些天真。

我认为审批唯一可靠的作用,是让一部分变更提报者知难而退。例如,规定所有生产变更都需要CTO审批,那么在点击提交按钮前,提变更的人至少会多掂量几次:“这个变更说明写到位了吗?真的值得为此去打扰CTO吗?”从这个角度看,审批是一种将压力折返给变更实施者的机制。

抛开审批不谈,大厂们这些年都在倡导“变更三板斧”。初听觉得有些口号化,但“可灰度、可监控、可应急”这九个字真要落地,说穿了就是做好三件基础事:测试或灰度环境要足够真实,监控指标要能真实反映问题,应急预案不能过于潦草。如果这些都做到了,剩下的就只能交给概率。分布式系统在面对足够大的请求量和足够复杂的交互时,没有哪个能做到100%可靠,所有链路叠加在一起就是一个庞大的概率模型。搞稳定性必须接受“一定会出问题”的事实,然后尽力将出问题的概率和造成的代价,压制在团队能够承受的范围内。

一块叫GitOps的石头

在控制变更这件事上,GitOps一度被寄予厚望。但最近一段时间,我经常被Terraform和Helm的变更计划(plan)吓出冷汗。一旦terraform plan执行后,屏幕上出现一片增删改(+/-/~)的标记,心里就会先“咯噔”一下:这些看似合理的差异(diff)里,有多少是我自己都没完全搞清楚其背后副作用的?

我曾是GitOps的坚定拥护者。在Google时,连生成一个监控仪表盘都要编写代码、经过代码评审(code review),更不用说日常的二进制部署。所有基础设施的状态,都定义在一堆文本文件中。那种感觉很奇妙:这个科技巨头的形态由一个巨大的单体代码库(monorepo)决定,只要代码在合并的那一刻是正确的,生产环境最终总会收敛到正确的状态。

但最近几年,我不得不承认一个现实:做了一半的GitOps半成品,有时候真不如一个简单直观的白屏操作表单。

常在河边走,哪有不湿鞋。SRE的日常工作中,充满了临时性变更:线上告警频发时,总有某个参数需要先手动调整;资源突增时,总得先紧急扩容几个节点再说。进行这些操作时,总不忘附带一句口头承诺:

“等稳定了再把配置写回Git仓库吧。”

然后,通常就没有下文了。

配置没有回写,文档没有更新,系统的真实状态只存在于某几台服务器的本地磁盘上。这时再来一次terraform apply,所有人就会一边在混乱中凌乱,一边高喊:

“我们需要加强变更保障!”

“我们需要铁三角会签审批!”

Google内部最早的发布系统叫sisyphus(西西弗斯),这个名字起得极为精妙。毕竟,无论是白屏化操作还是GitOps,本质上都在做同一件事:把名为“变更”的石头推上山去。在sisyphus体系里,所有变更都必须通过代码定义、经过code review,再在UI上进行一次确认操作(找到一张历史截图👇),你无法直接在生产环境手动修改。GitOps背后的文化隐喻,是对代码差异(diff)的尊重,也是对评审者有限注意力的尊重。

图片

建立如此标准的流程和配套工具是件很奢侈的事情。更多时候,code review逐渐流于形式,几行看起来无伤大雅的改动,被一句“LGTM(Looks Good To Me)”轻松放行,静悄悄地合并进主干代码库,然后在未来某个深夜,变成一条告警信息,出现在你的手机屏幕上。这时你是否会想起那些曾经耐心帮你审视细节的同事?一旦失去他们,任何代码仓库很快就会退化为一个结构化的“配置垃圾场”。

在AI时代,这件事变得更加微妙。生成代码的速度远远超过人类理解和评审的速度,diff一行行看上去都合情合理,却没人能说清哪一块是真正被某个责任人仔细斟酌后写出的。当我们把越来越多的实现细节“外包”给大模型,而剩下的人类连认真读一遍diff的耐心都难以保持时,Git上的提交历史依然完备,唯一消失的,是那个“我知道这行代码为什么在这里”的人。

西西弗斯的石头永远推不完,SRE面对的变更永远做不完,系统稳定性也永远达不到完美无缺的状态。我们能做的,大概就是把山坡修得平缓一些,提前想好石头滚偏了该往哪里接,多拉几个人一起站在坡上推,而不是一个人闷头向上冲。毕竟,万一真的力竭,石头落下来砸疼的终究是人,而不是AI。




上一篇:Python参数分类语法详解:/与*在函数设计与API维护中的实战应用
下一篇:末法时代做产品的不可能三角
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-24 19:22 , Processed in 0.260469 second(s), 38 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表