下午我在忙别的事。微信弹了一下。
是 Jerry。但不是每天下午五点的盘后简报,是一条我从没见过的消息:
Baoli,TideWatch 今天拉不到数据 😅
baostock 数据源连接超时,三只持仓的行情数据都拿不到,scan_market 也跑不动。可能是 baostock 服务端在维护或者网络问题。
我可以:
- 等一会儿再试(baostock 有时候会恢复)
- 你告诉我今天大致的行情,我手写一份简报
要我过一阵子自动重试吗?
我愣了一下,把手头的活放下。
不是报警,是报告
Jerry 值班整整 16 天了。从 4 月 6 号降生到今天,每天下午六点雷打不动——画一张持仓图、写一段朋友体简报、发到微信。
但它从来没遇到过塌方。
我想过它遇到塌方可能会怎样:stacktrace 截图、一串红色 ERROR、或者更糟——把 error message 当成正常数据渲染进图表,送我一张 score=None, price=None 的鬼图。
一个都没发生。我收到的是一条有判断的消息。
"一通检测下来"——他查了。"可能是 baostock 服务端在维护"——他给了假设。"我可以,1. ..., 2. ..."——他给了选项。最后一句,"要我过一阵子自动重试吗?"——他问我要不要授权。
一个值班生该做的事,全做了。
去核实
Jerry 再靠谱,故障判断这种事得我自己看。
本地跑一下 baostock——75 秒才 login 失败,三只股票全挂。SSH 到 Azure VM 再跑一遍——130 秒超时,同样挂。两地都在 login 阶段就断了,故障在 quote.baostock.com 的服务端。
Jerry 的判断是对的。
Dashboard 干净的
真正让我停下来的不是这个。是下一个问题:Dashboard 有没有被污染?
数据源挂了等恢复就行;但如果空数据已经写进缓存,覆盖了下午那次有效扫描——那才是真事故。
SSH 过去看:scan_cache.json 时间戳停在今天 13:18:04——baostock 挂掉之前那次扫描,32/32 全成功。今日新增 signals 记录 0 条。观潮自己活着,持仓卡片数据完整。
一点没污染。
之前为 baostock 不稳定架的四层防线全部在线:交易日闸门 early exit、空 df 直接 return error 不进 signals、成功率低于 50% 拒绝覆盖旧缓存、前端 adjusted_score != null 才写 detailCache。
数据源塌了,但免疫系统没塌。
监护,不是监控
这一天我才真正分清这两个词。
监控是:当 X 发生,发一条 alert 给人。贴到告警群,值班的人自己去处理。
监护是:当 X 发生,先冷静检测,给出判断,提出选项,等待授权。故障没消失,但它被翻译成了一段让人能接住的话。
区别在"翻译"那一步。
Jerry 不是 curl 失败就喊塌方。他看到超时之后,自己先排查了一轮——重试、换 symbol、看是不是单股问题——排除完才下"服务端问题"的判断。"一通检测下来"这五个字背后是 agency:他有权限去做诊断,也有判断力去解读结果。
一个值班生和一个报警脚本的差别,就是这五个字。
收束
baostock 什么时候恢复我不知道。可能一小时,可能明天早上。但今晚的 cron 就算触发,观潮的交易日闸门会判定 baostock 没返回数据 → skip。scan_cache 保留今天 13:18 的数据,signals 表 0 新增。
一切都会很安静。
16 天前那篇博文的结尾我写:"Jerry 不需要从零重建能力,它只需要学会一件事:翻译。"
今天他翻译的不是 scan_market 的 JSON。是一次故障。

