NodeJs 在多个节点上调度作业

Posted

技术标签:

【中文标题】NodeJs 在多个节点上调度作业【英文标题】:NodeJs scheduling jobs on multiple nodes 【发布时间】:2016-04-23 18:50:23 【问题描述】:

我有两个 nodeJs 服务器在负载均衡器后面运行。我有一些计划作业,我只想以分布式方式在两个实例中的任何一个上运行一次。

我应该使用哪个模块? node-quartz(https://www.npmjs.com/package/node-quartz) 对此有用吗?

【问题讨论】:

【参考方案1】:

添加 redis 和使用 node-redlock 对于我需要在负载均衡器后面的三个 Node.js 进程的单个服务器上安排每天一次的小型缓存作业来说似乎有点过头了。

我发现了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 秒,则两者都声称是第一进程。

【讨论】:

【参考方案2】:

我以前没有这样做过,但我可以看到自己这样做。

为 Node.js 使用任何调度程序库。

为了实现您的目标,我会使用 redis 进行分布式锁。在运行任何预定的作业之前,工作者/节点必须获得锁;做这项工作;并在完成工作(或出错)时释放 / ack()。

【讨论】:

两者同时尝试获取锁会发生什么? @VikasTiwari 你可以在redis.io redis.io/topics/distlock阅读更多关于redlock算法的信息【参考方案3】:

可以通过使用 Zoologist 包在可用实例中进行选举来选择单个服务器作为领导者

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

需要 Zookeeper 服务器进行选举

【讨论】:

【参考方案4】:

我不知道这是否对你有帮助,但仍然在这里发布。

通常node-schedule 用于基于时间的计划,您只需执行一次任意代码。例如:下个月下午 6:00 读取/写入数据库。

【讨论】:

【参考方案5】:

以下帖子将解释编写计划的作业,这些作业将根据我们对特定时间/日期实例的要求执行某些操作。

为了执行上述任务,我们将使用节点的 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,例如 * 总是。 每 5 分钟 0 - 59 / 5。

onTick:要执行的操作。

开始:它需要一个布尔值,如果为真则现在开始工作。

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);
 ;

希望对你有帮助。

【讨论】:

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

以上是关于NodeJs 在多个节点上调度作业的主要内容,如果未能解决你的问题,请参考以下文章

ETL作业调度软件TASKCTL4.1怎么安装?

在多节点环境中仅触发一次调度作业

怎么优化hadoop任务调度算法

进程调度算法

具有依赖作业/具有多个所需运行时间的作业的加权间隔调度

分布式资源调度--YARN框架