Node.js里面大量使用定时器会有问题吗?
发布于 7 年前 作者 TongCong 5793 次浏览 来自 问答

刚刚加了个新需求:

公司是做贷款的,用户注册完成后的一小时内如果没有去填写贷款信息,就发短息给用户提醒用户,填写了的话就不用发。

我想到的就是用定时器了,注册完成的时候,延迟一小时去查数据库,看看用户有没有填写贷款信息。如果有就不发,没有就发。

但是这样,用户量一多的话,就会有很多定时器同时在内存中,这样会有影响吗?

各位大佬还有什么好的其他实现思路?求解惑。。。

8 回复

定时不应该针对单个用户吧, 最好是一批好些。

查询出一批用户来,然后时间大于一小时候的,发短信通知。 你只要往数据库里插入数据就可以了。

  1. 事件队列增加大量timer感觉这个方案不是很好. 因为即使你什么都不做,event loop进入poll阶段(假如队列是空)也需要去等待timer的时间,而且timer也是有限制的。

官方 event loop timers

  1. 你完全可以在注册写入时加一个timestamp,做一个定时任务,去不断迭代执行。

用户注册后往redis中存一条数据,status = 0; time = 一小时后的时间; 如果用户填写了贷款信息将该条数据的 status 改为 1 ; 单独跑一个脚本,取出redis中的数据,如果 time 小于当前时间,且 status = 0。发提醒短信。 如果让我来做,大致思路是这样的。需要注意一些细节,比如 记录是否发短信的状态等等。 供参考!

Redis Keyspace Notifications

不要针对单个用户,可以定时批量处理,这样定时器就少多了。

定时器多,无非是 timer_queue 的队列很长,这样 如果每个 timer_cb 处理时间很长的话,这个很恐怖的。。。 eventloop 几个阶段中,timer 阶段占用大量时间的话,那么 poll 阶段里的 各种网络/io cb 得到执行的机会会变少。。。

这个其实有些问题的,主要是可能会丢,而且重启不方便,场景上完美适应消息队列,可以了解一下 @TongCong

建议使用事件队列,或者利用redis的键空间通知(keyspace notification)

回到顶部