Telegram服药提醒Bot优化:数据库推送式通知方案选型咨询
药物提醒Telegram机器人通知优化方案
针对你当前轮询数据库负载高的问题,下面给几个实用的推送式优化方案,按需选择:
一、PostgreSQL原生推送方案
不用额外加组件,直接用数据库自带机制搞定:
- 触发器+LISTEN/NOTIFY:给存药物暂停状态的表和
notification_time表加触发器——当药物切换暂停/恢复状态,或者新增、修改通知时间时,自动触发NOTIFY命令,把事件推给机器人应用。应用端启动后持续LISTEN对应的频道,收到事件就更新本地的有效通知缓存,不用再频繁查库。 - 配合pg_cron定时补全:安装pg_cron扩展,每天凌晨跑一次定时任务,把次日所有非暂停状态的药物通知批量同步到应用缓存。日常只有状态变更才会触发推送,大幅降低实时查询量。
二、消息队列调度方案
适合需要精准定时、状态变更响应快的场景:
- 延迟队列预调度:用户设置药物通知时,直接把每个提醒时间的任务丢到延迟队列(比如RabbitMQ的延迟插件、Redis的Sorted Set),队列到点自动把任务推给机器人发提醒。
- 状态同步机制:单独做一个小服务监听药物状态变更——药物暂停时,从队列里移除对应还没执行的任务;恢复时,重新把未完成的提醒任务塞回队列。小体量项目用Redis Sorted Set就够,把通知时间作为score,定时扫临近任务时直接跳过标记为暂停的任务。
三、代码层面轻量优化方案
不想加新组件的话,直接改现有轮询逻辑:
- 分层缓存策略:用本地缓存+Redis缓存存当前有效的(非暂停)通知列表。平时轮询先查缓存,只有缓存过期(比如设1小时有效期),或者检测到药物表最后更新时间比缓存新时,才去数据库同步数据。
- 增量+过滤查询:别每次全量拉
notification_time,改成只查下30分钟内要触发的、不在暂停药物ID列表里的通知,同时记录上次查询的最大时间戳,下次只查比这个晚的记录。另外单独维护一个暂停药物ID的缓存列表,查询时直接排除这些ID,减少数据处理量。
内容的提问来源于stack exchange,提问作者Torikki
相关产品推荐
相关产品推荐

