需求背景
有两张表,一张商品表存储了商品信息和商品过期日期(2022-06-10),另一张User表存储了用户设定的每日推送时间(6-23h)以及是否开启推送。
每天需要检索所有过期的商品,然后查询对应用户的推送时间,执行消息推送。假如每日需要推送数据量为5000次左右,如何设置定时任务和推送方案更合理?如果要推送的数据量更大呢?
技术环境:微信小程序的云函数(nodejs)
下面几个方案是我自己想的,但是每个方案都有弊端,希望大家给些思路
方案一:
每个小时执行一次定时任务,查询到所有开启推送逻辑且时间匹配的用户,遍历这些用户下所有需要当天推送的商品数据,按顺序依次执行推送事件。
优点:同一时间只会有一个定时任务,节约内存开支、逻辑简单
缺点:效率低,没有数据需要推送的用户也会被遍历、推送要排队,会导致推送不及时、用户修改推送时间后,可能会出现重复推送
方案二:
每日零点,查询商品表中所有要执行推送的数据(即过期时间匹配),遍历数据时同步查询该用户是否开启推送,以及推送时间,然后为所有符合条件的数据创建定时任务
优点:推送时间精准、不会出现重复推送的问题、匹配效率高
缺点:每一条推送数据都会创建一个定时任务,可能会导致服务器性能和并发问题、数据量大时需要分页遍历
方案三:
前两个方案结合,首先在每日零点查询商品表中所有要执行推送的数据,然后提取这些数据的推送时间、推送内容、推送用户id,存储到一张临时表。
然后每个小时执行一次定时任务,查询临时表中当前时间需要推送的数据,然后依次进行推送。所有数据推送完成后清空临时表。
优点:避免了创建大量定时器导致的性能和并发问题、匹配效率最高,每次定时任务只需一次查库动作
缺点:会出现推送排队,不及时的问题、逻辑变复杂,任何一个逻辑出错都可能会导致任务失败。
方案2里面的,「然后为所有符合条件的数据创建定时任务」,改为延时(迟)队列不就更合适嘛。