如何优雅的设计消息推送策略

需求背景

有两张表,一张商品表存储了商品信息和商品过期日期(2022-06-10),另一张User表存储了用户设定的每日推送时间(6-23h)以及是否开启推送。

每天需要检索所有过期的商品,然后查询对应用户的推送时间,执行消息推送。假如每日需要推送数据量为5000次左右,如何设置定时任务和推送方案更合理?如果要推送的数据量更大呢?
技术环境:微信小程序的云函数(nodejs)

下面几个方案是我自己想的,但是每个方案都有弊端,希望大家给些思路

方案一:

每个小时执行一次定时任务,查询到所有开启推送逻辑且时间匹配的用户,遍历这些用户下所有需要当天推送的商品数据,按顺序依次执行推送事件。

优点:同一时间只会有一个定时任务,节约内存开支、逻辑简单

缺点:效率低,没有数据需要推送的用户也会被遍历、推送要排队,会导致推送不及时、用户修改推送时间后,可能会出现重复推送

方案二:

每日零点,查询商品表中所有要执行推送的数据(即过期时间匹配),遍历数据时同步查询该用户是否开启推送,以及推送时间,然后为所有符合条件的数据创建定时任务

优点:推送时间精准、不会出现重复推送的问题、匹配效率高

缺点:每一条推送数据都会创建一个定时任务,可能会导致服务器性能和并发问题、数据量大时需要分页遍历

方案三:

前两个方案结合,首先在每日零点查询商品表中所有要执行推送的数据,然后提取这些数据的推送时间、推送内容、推送用户id,存储到一张临时表。

然后每个小时执行一次定时任务,查询临时表中当前时间需要推送的数据,然后依次进行推送。所有数据推送完成后清空临时表。

优点:避免了创建大量定时器导致的性能和并发问题、匹配效率最高,每次定时任务只需一次查库动作

缺点:会出现推送排队,不及时的问题、逻辑变复杂,任何一个逻辑出错都可能会导致任务失败。

阅读 3.1k
3 个回答

方案2里面的,「然后为所有符合条件的数据创建定时任务」,改为延时(迟)队列不就更合适嘛。

不管是推送什么消息,肯定是有触点的,通过这个触点触发消息推送功能,比如登录,比如打开某个页面,比如点击了某个按钮,或者某个接口等.
推送的信息,如果推送的信息是固定的话,可以将信息放入缓存,方便获取,可以使用定时任务定时刷新数据(主要看业务了)
然后就简单了,接口触发,后端返回数据.数据是放缓存的,所以快.. 如果还要更快的话可以考虑在客户端使用缓存.
如果是不同用户推送不同信息,那可能需要通过用户画像或者专门的配置来了.

已参与了 SegmentFault 思否社区 10 周年「问答」打卡 ,欢迎正在阅读的你也加入。

推荐方案 2.

  • 有条件的话,单独部署消息服务,这样就不会影响业务系统
  • 没条件且对时效不敏感的话,可以分批次推送,如每五分钟推送 1000 条

补充下:5000 次推送算极小量了,消息数量大的时候,还可考虑 MQ 或任务调度这种专业中间件,类似 Java 的 xxl-job

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题