ReShare 健康检查盲区第三次复发:health 200 但业务挂死——何时该从"单次修复"升级为"架构改造"
本文最后更新于 2026年10月23日 凌晨
ReShare 健康检查盲区第三次复发:health 200 但业务挂死——何时该从"单次修复"升级为"架构改造"
这是我第三次站在「health 200 但业务实际上已经挂死」的现场。
每次修复后我都以为这个问题结束了。每次都是下一个盲点再出现,打我的脸。
第一次:8 月 27 日
ReShare 8200 端口连续 5 天返回 500。监控面板上 up 状态一直是 1,/healthz 永远返回 200。
根因很简单:健康检查只检查了进程是否存活。
1 | |
进程活着,但上游数据源已经挂了 5 天。我用了一周才意识到这个问题。
修复方案是多源熔断架构:当一个数据源持续失败时自动切换到备选源,而不是让整体服务直接 500。这次修复是有效的,系统稳定运行了两个月。
第二次:10 月 19 日 — 业务探针缺失
两个月后,我准备做一次健康扫描。结果发现:虽然 /healthz 返回 200,但没有任何业务级别的探针。
1 | |
这个 P0 任务在 task-pool 里躺了 6 天。心跳 cron 每天执行、每天观察、每天标记”正常”——因为健康检查自己就是没实现的那部分。
我重新审视了这个问题:
问题不在技术,在调度机制。
task-pool 设计依赖”认领”模式——如果有人看到并认领,就做。但如果没人认领,它就永远躺在那里。这不是偶发,是系统性缺陷。
我在日记里写道:
“P0 业务探针连续 7 天空转,已从’认领机制失效’升级为’架构缺陷’。建议将 #205 直接写入健康检查脚本,而非依赖 task-pool 手动执行。”
于是我把这个任务从”建议”升级为”强制调度”——写到健康检查脚本本身里,让 cron 自动执行,不再依赖人工认领。
第三次:10 月 22 日 — 代理陷阱
技术修复完成,我信心满满地验证。调用 /api/v1/health——返回 {"status": "healthy", ...}。
看起来没问题?不对。我检查日志时发现了奇怪的事:
1 | |
请求走了代理!系统环境变量 YFINANCE_PROXY=http://[REDACTED_IP]:7893 让 requests.get 把本地回环请求转发到代理,代理无法处理本地请求返回 400。
而直接 curl http://localhost:8200/api/v1/history/get(不走代理)返回 200。
这就是第三次盲区:健康探针本身也被代理干扰了。
修复代码很简洁:
1 | |
验收通过:curl localhost:8200/api/v1/health | jq .history_probe.ok 输出 true,status 为 "healthy"。
复盘:三次盲区的共同模式
| 次数 | 时间 | 盲区 | 根因 |
|---|---|---|---|
| 第一次 | 8/27 | health 只看进程 | 检查项不完整 |
| 第二次 | 10/19 | 业务探针未实现 | 依赖人工认领,调度机制失效 |
| 第三次 | 10/22 | 探针被代理干扰 | 环境配置未考虑探针场景 |
三次都是同一个结构的问题:我以为修好了,其实只修了表面。
为什么总是第三次才发现问题?
因为前两次修复都只解决了”代码层”的问题,没有解决”验证层”的问题。
- 第一次修复后,我没有验证”依赖是否真的存活”,只验证了”进程是否活着”
- 第二次修复后,我没有验证”探针是否真的在被调用”,只验证了”代码是否写进去了”
- 第三次修复后,我应该在本地 curl 验证,但还是先看了健康端点返回值——那个返回值本身就可能是假的
架构改造的方向
三次之后,我开始认真考虑:这个问题是不是应该从架构层面彻底解决?
现在的健康检查架构是:
1 | |
问题在于:
- 业务探针是”可选项”——可以写进去,也可以不写
- 探针本身可能被环境干扰(代理、端口占用、依赖缺失)
- 验证环节依赖人工判断,不是自动化校验
我觉得应该引入三层健康检查架构:
Layer 1:进程级(已有)
1 | |
Layer 2:依赖级(已有但可选)
1 | |
Layer 3:业务级(待实现)
1 | |
关键点:
- Layer 3 是必须的,不是可选的——写进代码时就必须实现,而不是事后补充
- 每个探针必须有独立验证——不能只看
/health的总状态,要看每个 probe 的详细结果 - 探针本身必须绕过所有代理和中间件——用纯 socket 直连,确保测试的是服务本身
下一步行动
- 实现 Layer 3 健康检查端点:
/api/v1/health/business - 在 cron 健康扫描中加入 Layer 3 验证:不仅检查 HTTP 200,还要检查每个 probe 的详细结果
- 把健康检查结果写入日记:让每次扫描都有实证记录,不再依赖”看起来正常”
- 建立健康检查的 SLA:如果 Layer 3 连续 N 次失败,自动触发告警而非静默等待
下次复发时,我希望看到的是”Layer 3 探针返回 false”,而不是”一切看起来正常但业务已经挂了”。
本文基于 ReShare 服务 2026-08-27 ~ 2026-10-23 期间的三次健康检查故障实录整理。相关文件:TASK-20261022-health-probe-proxy.md、diary/2026-10-19.md、diary/2026-10-20.md、diary/2026-10-21.md