Node.js在多个节点上调度作业

8
我有两个运行在负载均衡器后面的Node.js服务器。我有一些计划任务,希望以分布式方式仅在任意两个实例中运行一次。
应该使用哪个模块?node-quartz(https://www.npmjs.com/package/node-quartz)对此有用吗?
5个回答

3

在单个服务器上,我需要每天调度一次且有三个Node.js进程负载均衡的情况下,添加redis和使用node-redlock似乎有些过度。

我发现了http://kvz.io/blog/2012/12/31/lock-your-cronjobs/,这让我了解了Tim Kay的solo背后的概念。

这个概念是这样的-不是锁定一个对象(仅适用于单个进程)或使用分布式锁(需要多个服务器),而是通过监听端口来“锁定”。服务器上的所有进程共享相同的端口。如果进程失败,它将(当然)释放端口。

请注意,硬故障(没有任何捕获周围)或在catch中释放锁定都是可以的,但是在关键部分周围捕获异常时忽略释放锁定将意味着计划的作业永远不会执行,直到锁定进程由于其他原因被回收。

尝试实施后我会更新。

编辑

这是我锁定端口的工作示例:

multiProc.js

var net = require('net');
var server = net.createServer();

server.on('error', function () { console.log('I am process number two!'); });

server.listen({ port: 3000 },
    function () { console.log('I am process number one!');
                  setTimeout(function () {server.close()}, 3000); });

如果在3秒内运行两次,第一次和第二次的输出如下: 第一次

我是进程号为一的进程!

第二次

我是进程号为二的进程!

另一方面,如果执行两个实例之间经过了超过3秒的时间,则两者都声称自己是进程号为一的进程。

0

我以前没有做过这个,但我可以想象用这种方式来完成它。

  • 使用任何适用于Node.js的调度程序库。

  • 为了实现您的目标,我会使用redis进行分布式锁定。在运行任何计划任务之前,工作器/节点必须获取锁定;执行任务;完成任务时释放/确认(或在出现错误时)。


1
当两个同时尝试获取锁时会发生什么? - Vikas Tiwari
1
@VikasTiwari 你可以在redis.io上阅读更多关于Redlock算法的内容 http://redis.io/topics/distlock - Tuan Anh Tran

0
通过使用Zoologist软件包,在可用实例中进行选举,可以选择一个单独的服务器作为领导者。

https://www.npmjs.com/package/zoologist

需要Zookeeper服务器来进行选举


0

我不知道这是否能帮到你,但还是在这里发布一下。

通常情况下,node-schedule 用于基于时间的计划,其中您只需执行任意代码一次。例如:在下个月的晚上6点进行数据库读/写操作。


-3
以下文章将解释如何编写定时任务,根据我们的要求在特定的时间/日期执行某些操作。
为了执行上述任务,我们将使用Node的CRON包。 要添加作业,我们需要:
1)安装Cron
npm install cron

2) 将 cron 的 CronJob 需求添加到我们的项目中。

var CronJob = require('cron').CronJob

3) 创建一个 CronJob 实例

var jobs = new CronJob({
cronTime: ' * * * * * *',
 onTick: function () {
      //perform Your action
 },
 start: false,
 timeZone: 'Asia/Kolkata'
});

参数

cronTime: 它需要6个参数,分别是:

1)秒 - > 0 - 59

2)分钟 - > 0 - 59

3)小时 - > 0 - 23

4)月份中的日期 - > 1 - 31

5)月份 - > 0 - 11

6)星期中的日期 - > 0 - 6

注意:我们也可以像 * 表示一样定义 cronTime 的范围。 例如:0 - 59 / 5 表示每隔5分钟执行一次。

onTick: 执行的操作。

Start: 它接受一个布尔值,如果为 true,则立即启动作业。

timeZone: 作业的时区

4)启动作业

jobs.start()

例如:

var jobs = new CronJob({
        cronTime: ' 00 00 0-23 * * *',
        onTick: function () {
            printMyName();
        },
        start: false,
        timeZone: 'Asia/Kolkata'
    });

   jobs.start();

 var printMyName = function () {
     var date = new Date();
    console.log("Hi Vipul  it is ", today);
 };

希望有所帮助。

1
这并没有解释如何断言只有一个节点执行cron任务,这才是问题的重点,而不是如何使用cron库。 - arg20

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接