CRON + Nodejs + 多核 => 行为?

Posted

技术标签:

【中文标题】CRON + Nodejs + 多核 => 行为?【英文标题】:CRON + Nodejs + multiple cores => behaviour? 【发布时间】:2015-08-22 16:56:00 【问题描述】:

我正在将一个类似 CRON 的模块构建到我的服务中(使用 node-schedule),这将成为我的多核设置的每个实例所必需的,我想知道它们都在运行自己的线程并且它们是所有计划在同一时间运行,它们会被每个线程调用还是只调用一次,因为它们都在加载相同的模块。

如果它们确实被多次调用,那么确保所需操作只被调用一次的最佳方法是什么?

【问题讨论】:

根据我的经验,它可以多次使用。我已经使用一个进程的端口号对其进行了过滤,但这不是我认为的正确方法。我也在等待替代解决方案.. 【参考方案1】:

如果你在集群模式下使用 pm2,那么可以使用 process.env.NODE_APP_INSTANCE 来检测哪个实例正在运行。您可以使用以下代码,这样您的 cron 作业只会被调用一次。

// run cron jobs only for first instance
if(process.env.NODE_APP_INSTANCE === '0')
    // cron jobs

【讨论】:

【参考方案2】:

node-schedule 在给定的节点进程内运行,它会安排特定节点进程要求它安排的事情。

如果您正在运行多个节点进程并且每个都使用节点调度,那么这些单独的节点进程中的所有节点调度实例都是独立的(它们之间没有合作或协调)。如果每个节点进程要求它自己的节点调度实例在每月第一个星期三下午 3 点运行特定任务,那么所有节点进程都将在那个时候开始运行该任务。

如果您只想执行一次操作,那么您必须在节点实例之间进行协调,以便该操作仅安排在一个节点进程中,而不是在所有节点进程中,或者仅将这些类型的操作安排在其中之一中您的节点实例,而不是全部。

【讨论】:

感谢您的澄清,对于如何在节点中协调此类操作是否有任何最佳实践? @Maruf 运气好吗?【参考方案3】:

以通用方式处理此问题的最佳方法是拥有一个共享数据库,您可以在其中写入“锁定”条目。例如,假设所有任务都写入了一个 DB 条目,例如 instanceId: "a", taskId: "myTask", timestamp: "2021-12-22:10:35"

所有任务都将提交相同的东西,除了它们自己的 instanceId。然后,您在“时间戳”上有一个唯一索引,因此只有 1 被接受。

然后他们都进行查询,看看他们的节点是否是被接受执行 cron 的节点。

您可以做同样的事情,但也可以添加一个“随机”字段来生成一个随机数,并且数字最小的任务获胜。

【讨论】:

以上是关于CRON + Nodejs + 多核 => 行为?的主要内容,如果未能解决你的问题,请参考以下文章

在 NodeJS 中安排一个异步函数

当代码在其他文件中时如何运行 Cron 作业 - Node JS

在多核服务器中使用带有集群的 socket.io 的好方法?

在nodejs中创建cluster

nodejs是单线程还是多线程

在 Nodejs Express 应用程序中单击按钮时启动/停止 cronjob