跳转至

被调度饿死的新闻源,和一份会报假警的体检报告

现象

我的舆情采集系统接了五个新闻源。巡检时发现其中一个交易所公告类源从建库第一天起就是零产出——几个月,零条。

按直觉这该是适配器坏了、被反爬了、或者接口改版了。都不是。同一个时期还发生了第二件事:健康检查报了一次"某日漏采"的告警,核查后发现那天根本没漏——一条不少地入了库。真缺口在另一个日子,安安静静地躺在那里,无人告警,也无法补救。

一个源被无声饿死几个月,一份体检报告既会报假警又对真缺口无能为力。这篇文章把两件事都解剖开。

直觉判断的盲区

"某个源几个月零产出",直觉的怀疑清单高度收敛:适配器坏了、被反爬了、接口改版了——这份直觉有坚实的统计基础,因为历史上绝大多数同类故障确实出在这三处。盲区在于它把采集器当成了系统的边界。这一次,采集器恰恰是全链路里最健康的部分:问题出在它上游的调度——分饭的顺序、截断的位置、去重标记的时机,三件事任何一件单看都无害。

同样被直觉放过的还有那份假告警:告警响了,直觉的反应是"去修被告警的问题",而不是"先验证告警本身对不对"。告警器也是被监控对象,也会生病——这条认知在告警响起的时候最难想起,恰恰因为它最该在那时候想起。

排查与关键证据

第一步,把采集器和调度拆开。 绕过调度直接调适配器打真实接口:正常返回,一次几十条。二分完成——问题不在采集器,在喂给它的调度。

第二步,顺主流程读调度逻辑。 两个因素复合:源列表的顺序里,这个源排在最后;主流程有一个全局总量截断。排最后的源永远分不到名额——饿死不是坏了,是分饭顺序决定的。

第三步,发现真正阴险的部分。 截断发生在去重缓存写入"已见"标记之后。也就是说:条目先被记为"已见",然后才被截断丢弃——下轮采集时它们已经是"见过的",永远不会被再采。被饿死不只是当下的损失,是有记忆的、不可逆的永久损失。 这是全文最值得划重点的一行。

第四步,用数据把故事钉死。 我把新闻库按"源 × 日"做了一次全量聚合,得到这篇文章的核心证据:

  • 该源从建库到修复日,每一个调度采集日都是零,唯一例外是一次手工运行(绕过了全局截断的执行路径)——手工跑就有,调度跑就没有,饥饿源实锤;
  • 修复(每源配额 + 按源轮转)后的第一个采集日起,该源每日稳定产出十几到三十几条,至今无一天缺席;
  • 配额的副作用同样清晰:原来独占名额的社区类源日均从三十多条降到十几条,资讯类源从约五条降到约两条——总入库量基本没变,变的是分配。配额不是为了多采,是为了不饿死。

第五步,解剖那份假体检报告。 健康检查的读取窗口用日历天、评估窗口用交易日,口径错位;叠加底层交易日历数据停更,两个各自正确的实现拼出了一个错误的告警。核查被告警的那一天:实际入库五十八条(各源分别四到三十二条不等),"漏采"不成立。而真正的缺口日(全天只入库了二十二条、且全部来自单一源)没有任何告警,也没有补采能力。

根因

  • 饿死根因:源顺序 × 全局截断 × 去重标记时序的复合效应。三个因素单独存在都不致命,任何一个位置调换都不会发生——复合故障的定义性特征。
  • 假告警根因:告警系统自身的读取窗口与评估窗口口径失配,外加它依赖的日历数据本身停更。告警器也是被监控对象,也会生病。
  • 组织层:有状态的丢弃(去重集合)从来没有被审计过——它丢了什么、丢了多少、还能不能找回,没有人知道。

约束与取舍

  1. 全局总量截断 → 每源配额 + 按源轮转。 代价:单源条数有了上限,社区类源的产出被明显压低;换到:任何单源都不会被饿死,单源异常被隔离,不再传染整条链路。
  2. 补采:放弃"自动重爬全量",改为按日回补计划。 代价:只能按缺口日粒度恢复,且被"已见"标记永久跳过的旧条目仍然找不回——是否清空去重缓存是一个显式取舍:清空会迎来一轮重复入库洪水,不清空则承认停机期间的部分永久损失。落地时保留了去重缓存:回补只走支持日期区间参数的交易所接口源,入库前仍经同一去重缓存过滤(幂等);页面类源只提供"最新列表"、结构上无法回补历史,其历史缺口被显式标记为不可回补——承认损失,而不是制造一轮重复入库洪水。
  3. 健康检查从"只告警"升级为"告警 + 补采 + 非零退出"。 代价:告警从通知变成待办,检查脚本出错会让定时任务显式失败——噪音换真实。
  4. 去重缓存没有过期机制(这一点在待办清单里明确记录过):公告类源依赖列表页滚动,长停机后恢复需要人工核查。这是一个已知并接受的债,文章里如实写出比隐瞒更有说服力。

可复用检查清单

  1. 多源配额调度里,截断必须发生在去重标记之前——顺序反了,被丢的条目永久损失;
  2. 排查"某源零产出",第一步永远是绕过调度直接打接口,先二分"采集器 vs 调度",别顺着直觉去查反爬;
  3. 健康检查的读取窗口、评估窗口必须同一口径、同一日历源;
  4. 有状态的丢弃(去重集合、黑名单、已见标记)要定期审计:丢了什么、多少、能否找回;
  5. 每条告警规则上线前先抽样复核它自己的历史告警——假告警率是告警系统自己的核心指标。