Node.js具有群集的周期性任务

时间:2015-03-28 12:29:35

标签: node.js loopbackjs strongloop periodic-task

我在生产模式下运行StrongLoop的Loopback API服务器。这意味着主进程会创建尽可能多的工作者,CPU拥有多少个核心。因此,主进程只控制工作人员,从不执行代码。

我的目的是当时只执行一次定期任务,因为现在它在所有4个工作程序上运行。

除了类似Redis的存储中的cron或'key lock'外,是否有任何建议?

1 个答案:

答案 0 :(得分:1)

在iojs和节点v0.12中,可以执行exclusive socket binding。这可以用作类似于基于文件系统的方法的锁定形式。两种方法都是相同的:

attempt exclusive access to resource
if success:
   perform task
else:
   do not perform task

使用套接字,您可以执行以下操作:

net.createServer().on('error', function(err) {
  console.log('did not get lock', err);
}).listen({ port: 4321, exclusive: true }, function() {
  singleProcessTask();
  this.close();
});

请注意,exclusive: true仅在群集模式下需要,因为它默认为共享套接字。

fs.open类似:

fs.open('lock.file', 'wx', function(err, fd) {
  if (err) {
    console.log('did not get lock', err);
  } else{
    singleProcessTask();
    fs.close(fd, function(err) {
      // insert error handling here
      fs.unlink('lock.file', function(err) {
        // insert error handling here
      });
    });
});

在这两种情况下,如果您的任务非常快并且您的流程的计时器时间表略有不同,则可能存在竞争条件。在这些情况下,任务仍然只能由一个进程一次执行,但每个计划的时间段可能会多次处理,具体取决于您实施计划的方式。

编辑更多说明性示例

var net = require('net');

var HOUR = 60*60*1000;

setInterval(myTask, HOUR);

function myTask() {
  locked(function() {
    // task code here
  });
}

function locked(fn) {
  net.createServer().on('error', function(err) {
    console.log('did not get lock', err);
  }).listen({ host: '127.0.0.1', port: 4321, exclusive: true }, function() {
    fn();
    this.close();
  });
}