1

StrongLoop の Loopback API サーバーをプロダクション モードで実行しています。これは、マスター プロセスが、CPU のコア数と同じ数のワーカーを作成することを意味します。したがって、マスター プロセスはワーカーのみを制御し、コードを実行することはありません。

私の目的は、定期的なタスクを一度に 1 回だけ実行することです。これは、4 つのワーカーすべてで実行されるようになったためです。

Redis のようなストレージでの cron または「キー ロック」以外の提案はありますか?

4

1 に答える 1

1

iojs とノード v0.12 では、排他的なソケット バインディングを行うことができます。これは、ファイルシステム ベースのアプローチと同様のロックの形式として使用できます。方法はどちらも同じです。

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

どちらの場合も、タスクが非常に高速で、プロセスのタイマー スケジュールがわずかに異なる場合、競合状態が発生する可能性があります。このような場合、タスクは一度に 1 つのプロセスによってのみ実行されますが、スケジューリングの実装方法によっては、スケジュールされた期間ごとに複数回処理される場合があります。

編集:より具体的な例

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();
  });
}
于 2015-03-29T18:42:22.763 に答える