Comment exécuter Cron Job dans l’application Node.js utilisant le module de cluster?

J’utilise le module node-cron pour la planification de tâches dans l’application Node.js. Je souhaite également exécuter l’application dans plusieurs processus à l’aide du module de cluster principal.

L’exécution d’une application dans plusieurs processus aboutit à l’exécution de tâches planifiées dans chaque processus (par exemple, si une tâche devait envoyer un courrier électronique, le courrier électronique serait envoyé plusieurs fois).

Quelles sont les meilleures pratiques / les moyens possibles d’exécuter le travail cron avec le module de cluster? Devrais-je créer un processus séparé qui ne gérera que le travail cron et n’acceptera aucune demande? Si oui, comment puis-je le faire correctement?

    Après quelques recherches, je me suis retrouvé avec la solution ” Serrures dissortingbuées avec Redis “. Il existe un module de noeud pour cela: node-redis-warlock .

    J’espère que cette réponse sera utile pour quelqu’un d’autre.

    MISE À JOUR . Exemple de code minimal:

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

    MISE À JOUR 2 . Exemple plus détaillé:

     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... 

    Si vous utilisez PM2 , vous pouvez utiliser une variable d’environnement fournie par PM2 elle-même, appelée NODE_APP_INSTANCE qui requirejs PM2 2.5 ou une version supérieure.

    NODE_APP_INSTANCE variable d’environnement NODE_APP_INSTANCE peut être utilisée pour déterminer la différence entre les processus. Par exemple, vous pouvez exécuter une tâche cron uniquement sur un processus. Vous pouvez simplement le faire.

    if(process.env.NODE_APP_INSTANCE == 0) { //schedule your cron job here since this part will be executed for only one cluster } ,

    Puisque deux processus ne peuvent jamais avoir le même numéro.

    Plus d’informations sur le document officiel PM2 ici .