Node/Express应用程序中延迟超过一小时的触发功能



我想在调用特定端点后延迟1小时或5小时触发express应用程序中的一个函数。

我试着在我的enpoint的then链中使用一个简单的setTimeout,在我的控制器中使用这样的东西:

function(req, res, next) {
return mailer.sendEmail(req.user, 'firstEmail') // returns a promise
.then(function(emailResult) {
if (emailResult == 'ok') {
res.sendStatus(200).json({ message: 'You will receive an email in 1 hour' }) // set positive API json response
} else {
res.sendStatus(200).json({ message: 'You will receive an email in 5 hour' }) // set negative API json response
}
return emailResult
})
.then(function(emailResult){
return new Promise((resolve, reject) => {
setTimeout(function(){
return return mailer.sendEmail(req.user, 'secondEmail')
}, emailResult == 'ok' ? 60 * 60 * 1000 : 5 * 60 * 60 * 1000) // 1 hour or 5 hours
})
}) 
})

似乎有效,但我有两个主要配音:

  • 如果我用(pm2-startOrReload-prod.json(重新启动应用程序的pm2进程,所有超时都会被取消吗
  • 如果我用这个系统安排了大约600次超时,我会有任何性能问题吗

有这样的经历吗?

像这样的超时可能是一种解决方案,但不是最好的解决方案。

如果超时会立即增加你的内存,比如每小时,当你重新启动Node.js进程时,尚未触发的计时器就会丢失,这意味着即使你试图更新新代码,如果你不想丢失任何计时器,你也无法重新启动应用程序。丢失电子邮件或永远不会重新启动,有点困惑,对吧?

对于这种情况,最常用的实现方法是消息队列。您可以将消息队列作为存储和使用在数据库中的计时器,这样您就不必担心计时器是否被取消或在不希望发生这种情况时被多次调用。

RabbitMQ是一个对Node.js.友好的独立MQ

Kue是一个类似MQ的NPM包,它依赖于Redis。

希望你喜欢。(

我已经遇到了这个问题。

我找到的解决方案是使用我的数据库作为时间寄存器。基本上,如果您使用的是SQL或面向文档的数据库:

  1. 将计划的操作插入数据库
  2. 每隔x秒检查一次(取决于您需要的准确性(是否有需要弹出的条目。如果是,删除该项目,接受它,执行它

您也可以使用cron包进行检查,但是。。。由于实现起来很简单,您应该自己完成。

编辑:为什么是这种解决方案?

首先,这是服务器的RAM保护程序,当您有大约5000个条目时,您不必将其存储在内存中。

  • 是的,所有超时都将被取消,因为它们存储在内存中
  • 我不认为600超时可能是个问题,但你可能会找到更合适的方法,比如用一个数组对所有超时进行排序,并用一个setInterval来检查是否需要执行一些东西

最新更新