简体   繁体   English

Node.js / Koa2服务器-在请求后几分钟执行作业

[英]Node.js/Koa2 server - execute a job minutes after request

I have a Koa2/Node.js app (using async/await ) and I want to execute a job X minutes after request, where X is a random number of minutes ranging from 20 - 100 (I want to use it to send automatic welcome emails to users who sign up and make it appear like it was sent personally by me). 我有一个Koa2 / Node.js应用程序(使用async/await ),我想在请求后X分钟执行作业,其中X是20至100之间的随机分钟数(我想用它来发送自动欢迎信息)给注册用户的电子邮件,并使其看起来像是我亲自发送的)。

So can I just use setTimeout to do this, is it reasonable to set a timer for 200 minutes? 所以我可以只使用setTimeout来做到这一点,将计时器设置为200分钟是否合理? Of course, if my app crashes, the email wouldn't be sent, but I will track all signups in database, so in a rare case of crash I will send the email myself. 当然,如果我的应用程序崩溃了,也不会发送电子邮件,但是我会跟踪数据库中的所有注册,因此在极少数的崩溃情况下,我会自己发送电子邮件。

Command queue such as rabbitMQ or wraps around Redis (with pub/sub or SETEX ) seems like an overhead for such simple task. 命令队列,例如rabbitMQ或环绕Redis的包装(使用pub / sub或SETEX )似乎对于此类简单任务来说是一项开销。

Timeouts for relatively long periods with potentially N requests do feel a bit uncomfortable, but Node.js setTimout() is actually a wrapper around uv_timer function in libuv which is designed to handle a huge amount of timers over the underlying OS notification mechanism. 对于潜在的N个请求相对长时间超时确实感到有点不舒服,但Node.js的setTimout()实际上是围绕一个包装uv_timer在功能libuv其目的是在底层操作系统的通知机制来处理庞大的定时器量。

Still, to keep things as simple as possible I would use a good old cron job with some wrapper library which hides exact implementation. 尽管如此,为了使事情尽可能简单,我将使用一个很好的cron作业,并使用一些包装器库来隐藏确切的实现。 With something like node-schedule it could be done in just few lines of code. 使用node-schedule之类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.
});

If something goes wrong during processing, referenced job can be cancelled: 如果在处理过程中出现问题,则可以取消引用的作业:

emailJob.cancel();

I hope your email contains random content as well, because even single user can get multiple messages in case of different signup attempts - so this delay could become just an annoying experience. 我希望您的电子邮件也包含随机内容,因为在不同的注册尝试情况下,即使是单个用户也可以收到多封邮件-因此这种延迟可能会变成令人讨厌的体验。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM