这一版没有新功能,只做了一件事:让轮询器少敲门。起因是打开钉钉管理后台的调用日志,看见自己的分身在以秒级频率拉会话消息接口,活跃时段还会反复撞上平台限流——表现为回复偶发地慢上一拍。

本文要点

  • 未读会话列表加 30 秒 TTL 缓存:它只决定「哪些会话优先抓」,新消息仍由主通道每轮全量拉取
  • 单聊对方信息解析失败进 5 分钟负缓存:外部好友、跨组织、网络瞬断不再每轮重打同一批元数据接口
  • 未读会话抓取加 30 秒下限间隔:从「每轮必抓」改为「最多每 30 秒一次」
  • 轮询间隔 10→20 秒、置顶列表缓存 120→180 秒、黑名单对账 10→20 轮、限流冷却 60→120 秒
  • 实测:接口调用总量降约 6–7 成,活跃时段限流熔断减半,改动后连续 18 分钟零熔断

现象:后台日志里的密集调用

钉钉管理后台(安全 > AI安全 > 调用管理)能看到分身账号的接口调用记录。截图里一分钟不到的时间窗内,同一会话消息接口被调了十几次,还经常是同一秒并发四五个——那是轮询器的受控并发在同时抓多个会话。问题不在并发本身,而在频率与重复:很多次调用拉回来的内容,和上一次完全一样。

更实际的后果是限流。日志里能看到平台在活跃时段反复返回 RATE_LIMIT_ERROR,熔断器虽然会暂停抓取 60 秒再恢复,但恢复的瞬间又要把攒下的会话一次性重抓,于是再次撞限流——一个自己喂自己的循环。

根因:四层各打各的

拆开看,重复调用来自四个地方,每一处单看都「合理」,叠在一起就是风暴:

做法:四层降频,各归其位

关键前提:为什么敢降频

敢动这几个开关的前提是:消息的主通道不是它们。系统真正收消息靠的是 list-all 主通道——每轮按时间窗全量拉取,命中即走「快通道」即时派发,不等后面的逐会话抓取。逐会话抓取(chat_message_list / chat_message_list_direct)只是健壮性冗余:外部好友、群消息这类主通道覆盖不到的兜底路径。

换句话说,被降频的是「冗余通道的重复确认」,不是「消息本身」。实测也印证了这一点:降频后消息照常进来,list-all 快通道持续派发,图片 OCR 正常,没有任何漏回。

降频的正确姿势不是「少查点」,而是先分清哪条是主动脉、哪条是保底,再决定保底要多勤。

实测

顺带修一个失真的统计

轮询日志里有一行「长尾限频跳过 N 个抓取」,此前恒为 0——限频命中的会话走的是提前返回路径,没被计入聚合返回值。降频做完却看不出效果,正是因为这行数字在骗人。现已改为独立计数,降频效果在日志里如实可见(上面那组 25–70 就是它打出来的)。

门禁

升级注意

无破坏性变更、无数据迁移。新增三个可调配置,默认值即降频后的取值;不想要降频可全部设为 0 回到旧行为。轮询间隔由 10 秒放宽到 20 秒,兜底通道的抓取延迟相应变长(主通道仍是每轮一遍),介意延迟可把 interval_seconds 调回 10。

延伸阅读