目录
1648 字
8 分钟
周五上线魔咒:部署日的玄学与事故

周五 17:20,群里有人问:这个小改动能上吗?

五分钟,没人回复。

17:25,他自己答:就一行,我上了。

17:31,他退出了群聊——不是主动的那种。

一、部署玄学博物馆#

「周五不部署」不是一条规定,它是一整套民俗。散落在各个公司的版本包括:

  • 只读星期五(Read-Only Friday):周五只读不写,上线窗口排在周二到周四;
  • 节前冻结:圣诞节、春节、大促之前,变更冻结,谁提需求谁背锅;
  • 看人下菜:老板出差前不部署、对外演示前一晚不升级、客户参观日只敢改文案;
  • 物理玄学:机房放苹果、服务器上贴「已稳定运行 xx 天」、sudo 之前先深呼吸。

这些规矩好笑,但它们并不迷信。每一条都是用组织记忆硬编码出来的风险控制——每条规矩背后都躺着一次事故。真正值得追问的是:它们防的到底是「星期五」,还是别的东西?

二、把段子拆开:周五到底危险在哪#

关键在这句:周五不会让代码更容易出错,它让错误更难被收拾。

  1. MTTR 变长。周三下午出事,值班的人五分钟就能进场;周五晚上出事,你得先等他放下筷子。
  2. 决策链变长。要不要回滚,得找审批的人;审批的人此刻在饭桌上,而回滚窗口是按分钟计价的。
  3. 变更规模变大。周五上的往往是攒了一周的合并——一周的改动挤进同一个窗口,一出问题,怀疑范围是整周。
  4. 注意力最低。周五下午的 review,LGTM 的含金量全年最低。

还有一个反直觉的数据:DORA / 《Accelerate》长期追踪的结论是,部署频率最高的团队,变更失败率反而更低。因为每次改动更小、更容易定位、回滚更快——「少发版更安全」是个错觉,「小步快发」才是解法。

所以「周五不部署」治的是症状。它把一个会痛的变更推到了周一,顺便让周一也变痛。

三、两个案例,日子都不是主角#

CrowdStrike,2024 年 7 月 19 日,星期五。 04:09 UTC,一次 Falcon 内容更新(Channel File 291)下发,内核里的内容解释器越界读内存,全球约 850 万台 Windows 设备蓝屏循环重启——航空公司、医院、银行的柜台一排排黑掉。更新在 78 分钟内被撤回,但已经蓝屏的机器只能一台台进安全模式手动删文件。事后复盘里有一句关键的话:这类内容更新没有灰度。

Knight Capital,2012 年 8 月 1 日,星期三。 为了对接纽交所新的零售流动性计划,公司部署了一批新代码——这批代码重新激活了路由里一段 2005 年就被挪了位置、早已废弃的函数。开盘后的 45 分钟里,路由器往市场发了 4000 多万笔订单,只为成交 212 笔客户委托,亏掉超过 4.6 亿美元。最扎心的是 SEC 事后查明:当天开盘前,内部系统已经自动发出了 97 封 报错邮件,没人看。星期三,上午九点半,一切看起来都很正常。

把两件事放在一起看:一个输在「没有灰度」,一个输在「部署流程没人复核」——没有一个输在星期几。

四、真正的解咒:把「部署」和「发布」拆开#

部署(deploy)是「把代码放上机器」,应该无聊、频繁、每天几十次;发布(release)是「让用户看到新功能」,应该可开关、可分组、可随时关掉。前者出问题最多回滚,后者出问题只需要关掉一个开关。

两件事粘在一起的时候,上面那些玄学就全回来了。

一个最小的开关实现,代码量比写一条上线公告还少:

type Flag = {
key: string
enabled: boolean // 总开关:出事了先关它,不用发版
rollout: number | string[] // 放量比例,或内测名单
}
// FNV-1a:同一个用户永远落在同一个桶里,不会刷新一次变一次
function hash(s: string): number {
let h = 2166136261
for (const ch of s) h = Math.imul(h ^ ch.charCodeAt(0), 16777619)
return h >>> 0
}
function isOn(flag: Flag, userId: string): boolean {
if (!flag.enabled) return false
if (Array.isArray(flag.rollout)) return flag.rollout.includes(userId)
return hash(userId + flag.key) % 100 < flag.rollout
}

有了它,17:30 上线就不再是赌博:先开 1%,盯五分钟指标,再开 10%、50%、100%。真出事,点一下开关,比 git revert + 重新构建 + 重新部署快一个数量级。

至于灰度、蓝绿、自动回滚、值班表,都是同一个思想的延伸:让每一次变更的影响范围小到可以承受,让每一次故障的处理动作小到可以随时执行。做到这两条,你就不需要「只读星期五」了——因为周三和周五没有区别。

五、周五上线自检清单#

发版前问自己四句:

  • 这次改动能一键回滚吗?回滚需要重新发版吗?
  • 出事了谁会醒?他知道回滚命令在哪吗?
  • 有没有开关能让它只对 1% 的用户生效?
  • 如果 17:30 上线、18:00 炸了,18:01 谁在场?

最后一条答不上来的时候,你怕的其实不是星期五,是自己那套流程。

写在最后#

段子继续讲,玄学继续拜——毕竟 sudo 前深呼吸不花钱。但心里要清楚:星期五只是一个变量名,事故的真正主题永远是「变更的影响范围」和「恢复所需的时间」。

所以下次有人在周五 17:20 问「这个能上吗」,最好的回答不是「不行」,而是:

能上。把开关关着推上去,周一再打开。

——这样星期五就赢了,而且是靠工程赢的。

参考来源#

延伸阅读:本博客里也有几篇讲「事故与人的距离」的文章——《历史上的著名 Bug》、《rm -rf 的悲惨故事》、以及昨天那篇《需求变更的经典笑话》(它有一节正好也在讲开关解耦)。

周五上线魔咒:部署日的玄学与事故
https://www.hehonglei.cn/posts/friday-deploy-curse/
作者
Honglei He
发布于
2026-09-27
许可协议
CC BY-NC-SA 4.0