外观
记一次线上问题排查:用户头像集体变默认
约 1509 字
随笔踩坑
记一次线上问题排查:用户头像集体变默认
讲一个自己遇到的线上事故(细节做了脱敏,但过程和教训是真的)。 这类「看着玄学、复盘低级」的案例,比成功案例有营养得多。
一、事故现象
周三下午,运营群里炸了:「用户头像全变成灰色默认头了! 客服电话被打爆!」
我登上生产环境一看,好家伙,大约六成用户的头像 显示为默认占位图。但诡异的是:
- 数据库里头像 URL 都在,没被清;
- 图片服务器(OSS)上的文件也在,能直接访问;
- 一部分用户(大约四成)的头像正常显示。
六成挂四成好,这个比例就很灵性。既不是全挂(排除整体故障), 也不是随机(排除网络抖动)。
二、瞎猜阶段(错误示范)
我第一反应是「今天上线的新版有问题」—— 上午刚发了一个 改头像组件的版本。于是:
- 回滚了头像组件 → 没用,该挂的还是挂;
- 怀疑 CDN 缓存 → 刷新缓存,没用;
- 甚至怀疑用户自己换了头像(运营:你清醒一点)。
半小时过去,毫无进展。这就是「瞎猜式排障」的代价: 每个猜测都 plausible,每个都没证据。 组长看不下去,过来问了一句:「日志呢?」 一句话点醒我 —— 我从头到尾没看过日志。
三、定位过程
图:从炸群到恢复的全过程,半小时花在瞎猜上
第一步:看接口返回
Network 面板复制一条头像请求(Copy as cURL 大法), 在终端里跑:
curl -I "https://cdn.example.com/avatar/u_10086.jpg"返回:
HTTP/1.1 403 Forbidden
x-oss-error-code: AccessDenied403!不是 404(文件不存在),是没权限。 文件还在,只是读不了。
第二步:缩小范围
写个脚本,拿一百个用户的头像 URL 批量跑,统计:
for id in $(seq 10001 10100); do
code=$(curl -s -o /dev/null -w "%{http_code}" "https://cdn.example.com/avatar/u_$id.jpg")
echo "$code"
done | sort | uniq -c结果:
59 200
41 403「好的/挂的」比例和用户侧完全对上(六四开)。 问题确认在 CDN/OSS 侧,不是前端、不是数据库。
第三步:找规律
对比 200 和 403 的文件 URL,发现一个特征: 403 的文件路径里都带 /avatar/,而正常的都在 /avatar-v2/。
去代码里搜 /avatar/,真相大白:
三个月前做了一次头像目录迁移,新上传的头像存 /avatar-v2/, 老的在 /avatar/。当时给 OSS 的 bucket 配了定时清理任务: 清理「90 天前的文件」—— 但配置时图省事,清理规则写的是 /avatar/* 整个前缀,没排除正在使用的目录。 今天刚好踩到 90 天界限,一批老头像被自动清理策略 标记成了「无引用文件」,权限被收。
至于为什么是「403」而不是「404」:清理任务先改 ACL 再删文件, 我们抓到了中间态。
四、修复与止损
- 紧急恢复:从数据库里存的 URL 列表,把被改 ACL 的文件 权限批量刷回来(跑了个脚本,十分钟搞定);
- 修正清理规则:清理任务加白名单,
/avatar/*排除,只清理真正确认无引用的临时目录; - 补监控:给头像接口加了「5xx/4xx 比例超过 5% 告警」, 下次这种事分钟级发现,不等用户投诉。
从炸群到恢复,总共一小时十分。但从炸群到找到方向, 花了半小时 —— 全是瞎猜耗掉的。
五、复盘:值一顿火锅的教训
教训一:先看日志和现象,再猜原因。 「回滚试试」是最廉价的动作,所以最 tempting。 但回滚只能回答「是不是新版本的问题」,回答不了 「问题在哪」。先复现、先看数据,再动手。
教训二:用数据缩小范围,别用想象。 「六成挂四成好」这个信息量巨大 —— 全挂是基础设施, 部分挂是数据/策略问题。写个循环脚本批量探测, 比盯着单个案例猜高效一百倍。定位问题本质是 分类讨论 + 排除法,不是灵光一闪。
教训三:自动化任务要当「代码」审。 清理脚本、定时任务、运维配置,出了事都是事故。 这次根因是三个月前一条「图省事」的清理规则。 所有会自动跑的东西,都要有审核和日志, 和上线代码一个标准。
教训四:监控告警是底线建设。 这次靠用户投诉发现问题,本身就说明监控有洞。 接口错误率、核心资源可用性,这些监控不是 KPI, 是安全带。可以不用,不能没有。
教训五(给自己的):出事后最怕的不是技术难,是心态崩。 被一群人在群里 @ 的时候,手都是抖的,越急越乱。 后来学到一个口诀:「先止损,再定位,后复盘」 —— 哪怕定位不了,先想办法恢复服务(比如切兜底头像), 把影响压到最小,再慢慢查。用户不关心你的排查过程, 只关心什么时候好。
六、后来
那次之后,我们把所有 OSS bucket 的定时任务盘了一遍, 清理掉三个「不知道谁配的」任务,剩下的全部加了 白名单和审批。头像目录迁移这种操作,也定了规范: 旧目录至少保留半年,清理前跑一遍「引用检查」。
现在回头看,这次事故最值钱的不是技术定位过程, 是让我记住了:线上问题,七分靠看,三分靠猜。 别让那三分抢跑。