我有一个 Koa2/Node.js 应用程序(使用async/await
),我想在请求后X分钟执行作业,其中X是 20 到 100 之间的随机分钟数(我想用它向用户发送自动欢迎电子邮件谁注册并使它看起来像是我亲自发送的)。
那么我可以只用setTimeout
这样做吗,将计时器设置为200分钟是否合理?当然,如果我的应用程序崩溃,电子邮件将不会发送,但我会跟踪数据库中的所有注册,所以在极少数崩溃的情况下,我会自己发送电子邮件。
我有一个 Koa2/Node.js 应用程序(使用async/await
),我想在请求后X分钟执行作业,其中X是 20 到 100 之间的随机分钟数(我想用它向用户发送自动欢迎电子邮件谁注册并使它看起来像是我亲自发送的)。
那么我可以只用setTimeout
这样做吗,将计时器设置为200分钟是否合理?当然,如果我的应用程序崩溃,电子邮件将不会发送,但我会跟踪数据库中的所有注册,所以在极少数崩溃的情况下,我会自己发送电子邮件。
诸如rabbitMQ 之类的命令队列或环绕Redis(使用 pub/sub 或SETEX
)对于这种简单任务来说似乎是一种开销。
可能有 N 个请求的相对较长时间的超时确实让人感觉有点不舒服,但 Node.jssetTimout()
实际上是一个封装uv_timer
函数,libuv
旨在处理底层操作系统通知机制上的大量计时器。
尽管如此,为了让事情尽可能简单,我会使用一个很好的旧 cron 作业和一些隐藏确切实现的包装库。node-schedule
只需几行代码就可以完成类似的事情。
const schedule = require('node-schedule');
const getRandomMsAmount = (from, to) => {
const minutes = Math.floor(Math.random() * to) + from;
return minutes * 60 * 1000;
};
const getDateAfterMs = (ms) => {
const nowTimestamp = Number(new Date());
return new Date(nowTimestamp + ms);
};
const dueDate = getDateAfterMs(getRandomMsAmount(20, 100));
const emailJob = schedule.scheduleJob(dueDate, () => {
// logging, updating database, etc.
});
如果在处理过程中出现问题,可以取消引用的作业:
emailJob.cancel();
我希望您的电子邮件也包含随机内容,因为即使是单个用户也可以在不同的注册尝试情况下收到多条消息 - 所以这种延迟可能只是一种烦人的体验。