如何在使用群集模块的Node.js应用程序中运行Cron Job? [英] How to run Cron Job in Node.js application that uses cluster module?
问题描述
我正在使用 node-cron 模块在Node.js应用程序中调度任务。我还想使用核心集群模块在多个进程中运行该应用程序。
I'm using node-cron module for scheduling tasks in Node.js application. I also want run the application in several processes using core cluster module.
在多个进程中运行应用程序最终会在每个进程中按计划执行任务(例如,如果任务是发送电子邮件,则电子邮件将被多次发送)。
Running application in several processes ends up in scheduled tasks execution in each process (e.g. if task was to send an email the email would be sent multiple times).
与集群模块一起运行cron作业的最佳实践/可行方法是什么?我应该创建一些单独的进程来处理仅cron作业,而不接受任何请求。如果是,我该如何以正确的方式做到这一点?
What are the best practices/possible ways of running cron job along with cluster module? Should I create some separate process which will handle only cron job and do not accept any requests. If yes, how can I do that in a right way?
推荐答案
经过一番研究,我最终得出了 使用Redis的分布式锁。
为此,有一个节点模块: node-redis-warlock 。
After some research I ended up with "Distributed locks using Redis" solution. There is node module for that: node-redis-warlock.
希望这个答案对其他人有用。
Hope this answer will be useful for someone else.
更新。最小示例代码:
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();
});
UPDATE 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...
这篇关于如何在使用群集模块的Node.js应用程序中运行Cron Job?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!