首页 > 解决方案 > 如何处理运行时间超过 cron 间隔的 pm2 cron 作业?

问题描述

我有一个在 pm2 上运行的 cron 作业,它每隔 5 秒发送一次通知。虽然它永远不会发生,但我担心脚本运行时间会超过 5 秒。基本上,如果上一次运行需要 6 秒,我不想在第一次运行完成之前开始下一次运行。有没有办法只在 pm2 中处理这个问题?我发现的所有内容都说使用 shell 脚本来处理它,但在需要时复制和移动到新服务器并不容易。

到目前为止,我的 cron 作业只是在一个永无止境的 while 循环中运行(除非有错误),最后等待长达 5 秒。如果它出错,它会退出并报告错误,然后重新启动,因为它是通过 pm2 运行的。不过,我对这个实现并不太兴奋。还有其他选择吗?

编辑以澄清我当前的逻辑 -

function runScript() {
  while (!err) {
    // do stuff
    wait(5 seconds - however long 'do stuff' took) // if it took 1 second to 'do stuff', then it waits 4 seconds
  }
}

runScript()

这感觉像是一种绕过 pm2 的 cron 限制的 hacky 方法。我可能只是偏执...我只是想确保我没有使用反模式。

标签: node.jsexpresspm2

解决方案


你是什​​么意思你让cron作业在while循环中运行?PM2 正在启动一个节点进程,其中包含一个等待 5 秒的永无止境的 while 循环?在我看来,您对 cron 的实现似乎不合适,也许您可​​以提供更多详细信息。

setTimeout我会使用类似方法的东西,而不是 cron 。使用 PM2 运行您的脚本,脚本中的方法如下:

function sendMsg() {
  // do the work

  setTimeout(sendMsg, 5000); // call sendMsg after waiting 5 seconds
}

sendMsg();

通过这种方式,您的 sendMsg 函数可能会占用它需要运行的所有时间,并且下一次调用将在 5 秒后开始。如果 PM2 崩溃,它将重新启动您的应用程序。

如果您希望以特定的 5 秒间隔执行此操作,但仅在该方法未运行时,只需在等式中添加一个跟踪变量,例如:

let doingWork = false;

function sendMsg() {
  if (!doingWork) {
    doingWork = true;
    // do the work
    doingWork = false;
  }
}

setInterval(sendMsg, 5000); // call sendMsg every 5 seconds

您可以用setInterval脚本上的 PM2 cron 调用替换,但变量的想法保持不变。


推荐阅读