epi*_*a30 22 cron cluster-computing node.js
我正在使用node-cron模块来调度Node.js应用程序中的任务.我还想使用核心集群模块在几个进程中运行应用程序.
在多个流程中运行应用程序最终会在每个流程中执行计划任务(例如,如果任务是发送电子邮件,则会多次发送电子邮件).
运行cron作业和集群模块的最佳实践/可能方法是什么?我应该创建一个单独的进程,只处理cron作业,不接受任何请求.如果是,我怎么能以正确的方式做到这一点?
Rah*_*mar 17
如果使用PM2,您可以使用由PM2本身提供的环境变量,该环境变量NODE_APP_INSTANCE需要PM2 2.5或更高版本.
NODE_APP_INSTANCE 环境变量可以用来确定进程之间的差异,例如你可能只想在一个进程上运行一个cronjob,你可以这样做
if(process.env.NODE_APP_INSTANCE == 0) {
//schedule your cron job here since this part will be executed for only one cluster
}
,
由于两个进程永远不会有相同的数字.
在PM2官方文档更多信息在这里.
epi*_*a30 11
经过一些研究后,我最终得到了" 使用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();
});
Run Code Online (Sandbox Code Playgroud)
更新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...
Run Code Online (Sandbox Code Playgroud)
小智 5
我认为您可以使用节点集群模块,并且您可以编写代码以仅在主集群中运行
const cluster = require('cluster');
if (cluster.isMaster) {
// Write your code which you want to execute in the master cluster only
}
Run Code Online (Sandbox Code Playgroud)
这是处理集群的节点方式,当然,您可以使用任何工具(例如 pm2)来处理此问题。
| 归档时间: |
|
| 查看次数: |
4392 次 |
| 最近记录: |