Node.jsアプリケーションでタスクをスケジュールするためにnode-cronモジュールを使用しています。また、コアクラスターモジュールを使用して、いくつかのプロセスでアプリケーションを実行したいと思います。
複数のプロセスでアプリケーションを実行すると、各プロセスでスケジュールされたタスクが実行されます(たとえば、タスクが電子メールを送信する場合、電子メールは複数回送信されます)。
クラスタモジュールと一緒にcronジョブを実行するためのベストプラクティス/可能な方法は何ですか?cronジョブのみを処理し、要求を受け入れない別のプロセスを作成する必要があります。はいの場合、どうすれば正しい方法でそれを行うことができますか?
いくつかの調査の後、私は「Redisを使用した分散ロック」ソリューションに行き着きました。そのためのノードモジュールがあります:node-redis-warlock。
この答えが他の誰かに役立つことを願っています。
更新。最小限のサンプルコード:
var Warlock = require('node-redis-warlock'),
redis = require('redis');
// Establish a redis client
redis = redis.createClient();
// and pass it to warlock
var warlock = new Warlock(redis);
function executeOnce (key, callback) {
warlock.lock(key, 20000, function(err, unlock){
if (err) {
// Something went wrong and we weren't able to set a lock
return;
}
if (typeof unlock === 'function') {
setTimeout(function() {
callback(unlock);
}, 1000);
}
});
}
// Executes call back only once
executeOnce('every-three-hours-lock', function(unlock) {
// Do here any stuff that should be done only once...
unlock();
});
更新2。より詳細な例:
const CronJob = require('cron').CronJob;
const Warlock = require('node-redis-warlock');
const redis = require('redis').createClient();
const warlock = new Warlock(redis);
const async = require('async');
function executeOnce (key, callback) {
warlock.lock(key, 20000, function(err, unlock) {
if (err) {
// Something went wrong and we weren't able to set a lock
return;
}
if (typeof unlock === 'function') {
setTimeout(function() {
callback(unlock);
}, 1000);
}
});
}
function everyMinuteJobTasks (unlock) {
async.parallel([
sendEmailNotifications,
updateSomething,
// etc...
],
(err) => {
if (err) {
logger.error(err);
}
unlock();
});
}
let everyMinuteJob = new CronJob({
cronTime: '*/1 * * * *',
onTick: function () {
executeOnce('every-minute-lock', everyMinuteJobTasks);
},
start: true,
runOnInit: true
});
/* Actual tasks */
let sendEmailNotifications = function(done) {
// Do stuff here
// Call done() when finished or call done(err) if error occurred
}
let updateSomething = function(done) {
// Do stuff here
// Call done() when finished or call done(err) if error occurred
}
// etc...
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加