如何在使用群集模块的Node.js应用程序中运行Cron Job? [英] How to run Cron Job in Node.js application that uses cluster module?

查看:123
本文介绍了如何在使用群集模块的Node.js应用程序中运行Cron Job?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆