事故概述与直接损失 - 公司因一个线上P0级事故导致客户服务中断7小时,并因此赔付客户十万人民币 [1] - 事故的直接技术原因是package.json文件中,对一个内部核心工具库@internal/core的依赖项版本号前缺少了脱字符^,导致版本被锁死 [1][7] - 当该内部库修复严重性能Bug并发布新版本(1.3.6)后,原项目无法自动获取更新 [8] - 内部库同事为保持仓库整洁,删除了旧的1.3.5版本git tag,导致项目部署时因找不到指定版本而构建失败,服务崩溃 [12][13][14] 对依赖管理认知的偏差与教训 - 团队此前对package.json中版本符号^和~的作用理解不足,误以为依赖更新会自动发生 [15][21] - 对lock文件(如pnpm-lock.yaml)的理解过于浅显,仅视其为缓存,未认识到它是保证多环境依赖树一致性的关键文件,必须提交到Git仓库 [18][20] - 依赖更新应被视为一个严肃的、需要主动管理和测试的行为,而非被动接受的过程 [22] 改进后的依赖管理规范与流程 - 团队现已强制规定,所有package.json中的依赖必须使用^符号,以自动获取非破坏性的小版本和补丁更新 [16][17] - 明确了版本符号的含义:^1.3.5允许安装1.x.x(x>=5)的最新版本,是推荐写法;~1.3.5仅允许1.3.x(x>=5)的补丁更新,过于保守;无符号则代表锁死版本,在业务项目中应避免使用 [17] - 建立了新的依赖更新主动管理流程:1) 使用pnpm update --interactive筛选可安全更新的包;2) 在本地进行完整测试;3) 将更新后的lock文件通过单独PR提交;4) 在CI/CD的staging环境中进行完整的端到端测试验证 [30]
就因为 package.json 里少了个 ^ 号,我们公司赔了客户 10 万
程序员的那些事·2025-12-09 13:24