ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

微信推送的“省着用“设计

微信推送的“省着用“设计

文章目录

    • 约束
    • 设计:三级分流
    • 队列:JSONL + 文件锁
    • Digest:每小时整理一次
    • 配额:三层防线
    • 为什么不用消息队列中间件
    • 总结

约束

通过官方通道给微信发消息,有个硬约束:全天主动发送上限 10 条。超过就发不出去。

10 条什么概念?系统里跑着几十个定时任务:邮件分拣、考研监测、福利领取、账号监控……每个都想推一条,分分钟超标。

设计:三级分流

┌─ 紧急 ──→ 立刻推送 待推送事项 ──┤ └─ 非紧急 ─→ 入队 → 定时 digest 合并发送

紧急标准(今天/明天内必须处理,错过即实质损失):

  • 截止类提醒(报名、缴费、兑换码先到先得)
  • 审核不通过需补材料
  • 账号异常

非紧急(重要但可以等):简报、周报、价格政策变化等。

紧急的直接调发送脚本立刻发;非紧急的写入队列文件,等 digest 任务整理。

队列:JSONL + 文件锁

队列就是个 JSONL 文件,每行一条:

{"ts":"2026-10-15T14:30:00","source":"inbox-scan","text":"内容","sent":false}

写入时加文件锁(fcntl.flock),防止多个任务同时写坏文件。实现很简单,30 行 Python。

Digest:每小时整理一次

digest 任务每小时跑一次,触发条件(满足一条才发):

  • 队列中待发送 ≥ 3 条,或
  • 最早一条等待 ≥ 3 小时

整理步骤:

  1. 配额检查:先数今天已发了几条,≥ 8 条就跳过(给紧急推送留 2 条余量)
  2. 去重:内容相似的合并为一条
  3. 排序:按重要性排
  4. 压缩:200 字以内一条发完,实在放不下最多分 2 条

发送成功后,已发送条目移出队列、记入已发送日志;失败的不重试,留到下次。

配额:三层防线

超标是最不能接受的,做了三层防线:

  1. 发送脚本内置检查:每次发送前数今天的发送日志,≥ 10 条直接拒绝
  2. digest 预留余量:digest 在 8 条就停手,留 2 条给紧急推送
  3. 审计日志:每次发送记一行,方便事后对账

为什么不用消息队列中间件

想过用 Redis/RabbitMQ,但:

  • 就一个 JSONL 文件能解决的事,没必要引入服务
  • 文件锁在单机场景够用了
  • 少一个依赖,少一个故障点

总结

这套机制跑下来,最大的体会是:约束越硬,设计越要简单。10 条的限制逼着我把"什么值得打扰用户"想清楚——紧急的定义、合并的规则、余量的预留,每个数字背后都是一次取舍。

给做类似系统的建议:先定配额,再定分级,最后才是实现。顺序反了,代码写得再漂亮也是错的。


以上,全文完。

如果这篇文章对你有帮助,欢迎点赞收藏,也欢迎在评论区交流你的做法。

欢迎关注我的 CSDN 博客:https://blog.csdn.net/2301_80281820

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进