在nodejs中使用cron与redlock和cluster

我想每分钟运行一次任务,为此我select了cron。 现在我正在运行使用集群模块的节点,它产生了4个进程,但是我希望每分钟每进程只运行一次cron。

现在解决这个问题的方法就是在master中运行它。 但是,如果我在每个实例上启动多个集群实例,那就没有用处。

所以我决定寻找locking机制。 我发现了redlock,这是示例代码:

const redlock = new Redlock([redisClient], { driftFactor: 0.01, // time in ms retryCount: 2, retryDelay: 200 // time in ms }); redlock.on('clientError', function (err) { console.error('REDLOCK REDIS ERROR: ', err); }); const LOCK_KEY = "GOHAN_REMINDER_LOCK"; const LOCK_KEY_TTL = 10000; const job = new CronJob({ cronTime: '* * * * *', onTick: function () { /* * Runs every minute */ redlock.lock(LOCK_KEY, LOCK_KEY_TTL).then(function (lock) { return Bluebird.try(function () { const currentMilitaryTime = moment.utc().format("HH:mm"); return ChildReminder.getRemindersByDate(currentMilitaryTime).then(function (reminders) { console.log("REMINDERS FOR TIME " + currentMilitaryTime + " :", reminders); }); }).then(function () { return lock.unlock() .catch(function (err) { console.error("REDLOCK UNLOCK ERROR: ", err); }); }); }); }, start: false, timeZone: 'UTC' }); job.start(); 

我得到的日志:

 REMINDERS FOR TIME 06:08 : [ anonymous { user_id: '764418c2-a874-495c-b8c1-cc555ce9b202', child_id: '8c8a273f-3a84-4a66-9fa7-bb9e6c5fcf0a', reminder_id: 4, label: 'textvoice1', mode: 'textvoice', text_message: 'How you doin\'', voice_message: '1480399630', created_at: 2016-11-29T06:07:12.296Z, updated_at: 2016-11-29T06:07:12.296Z, time: '06:08', repeat: '1111111', on: true }, anonymous { user_id: '764418c2-a874-495c-b8c1-cc555ce9b202', child_id: '8c8a273f-3a84-4a66-9fa7-bb9e6c5fcf0a', reminder_id: 5, label: 'textvoice1', mode: 'textvoice', text_message: 'How you doin\'', voice_message: '1480399638', created_at: 2016-11-29T06:07:19.385Z, updated_at: 2016-11-29T06:07:19.385Z, time: '06:08', repeat: '1111111', on: true } ] REMINDERS FOR TIME 06:08 : [ anonymous { user_id: '764418c2-a874-495c-b8c1-cc555ce9b202', child_id: '8c8a273f-3a84-4a66-9fa7-bb9e6c5fcf0a', reminder_id: 4, label: 'textvoice1', mode: 'textvoice', text_message: 'How you doin\'', voice_message: '1480399630', created_at: 2016-11-29T06:07:12.296Z, updated_at: 2016-11-29T06:07:12.296Z, time: '06:08', repeat: '1111111', on: true }, anonymous { user_id: '764418c2-a874-495c-b8c1-cc555ce9b202', child_id: '8c8a273f-3a84-4a66-9fa7-bb9e6c5fcf0a', reminder_id: 5, label: 'textvoice1', mode: 'textvoice', text_message: 'How you doin\'', voice_message: '1480399638', created_at: 2016-11-29T06:07:19.385Z, updated_at: 2016-11-29T06:07:19.385Z, time: '06:08', repeat: '1111111', on: true } ] REMINDERS FOR TIME 06:08 : [ anonymous { user_id: '764418c2-a874-495c-b8c1-cc555ce9b202', child_id: '8c8a273f-3a84-4a66-9fa7-bb9e6c5fcf0a', reminder_id: 4, label: 'textvoice1', mode: 'textvoice', text_message: 'How you doin\'', voice_message: '1480399630', created_at: 2016-11-29T06:07:12.296Z, updated_at: 2016-11-29T06:07:12.296Z, time: '06:08', repeat: '1111111', on: true }, anonymous { user_id: '764418c2-a874-495c-b8c1-cc555ce9b202', child_id: '8c8a273f-3a84-4a66-9fa7-bb9e6c5fcf0a', reminder_id: 5, label: 'textvoice1', mode: 'textvoice', text_message: 'How you doin\'', voice_message: '1480399638', created_at: 2016-11-29T06:07:19.385Z, updated_at: 2016-11-29T06:07:19.385Z, time: '06:08', repeat: '1111111', on: true } ] REMINDERS FOR TIME 06:08 : [ anonymous { user_id: '764418c2-a874-495c-b8c1-cc555ce9b202', child_id: '8c8a273f-3a84-4a66-9fa7-bb9e6c5fcf0a', reminder_id: 4, label: 'textvoice1', mode: 'textvoice', text_message: 'How you doin\'', voice_message: '1480399630', created_at: 2016-11-29T06:07:12.296Z, updated_at: 2016-11-29T06:07:12.296Z, time: '06:08', repeat: '1111111', on: true }, anonymous { user_id: '764418c2-a874-495c-b8c1-cc555ce9b202', child_id: '8c8a273f-3a84-4a66-9fa7-bb9e6c5fcf0a', reminder_id: 5, label: 'textvoice1', mode: 'textvoice', text_message: 'How you doin\'', voice_message: '1480399638', created_at: 2016-11-29T06:07:19.385Z, updated_at: 2016-11-29T06:07:19.385Z, time: '06:08', repeat: '1111111', on: true } ] REMINDERS FOR TIME 06:08 : [ anonymous { user_id: '764418c2-a874-495c-b8c1-cc555ce9b202', child_id: '8c8a273f-3a84-4a66-9fa7-bb9e6c5fcf0a', reminder_id: 4, label: 'textvoice1', mode: 'textvoice', text_message: 'How you doin\'', voice_message: '1480399630', created_at: 2016-11-29T06:07:12.296Z, updated_at: 2016-11-29T06:07:12.296Z, time: '06:08', repeat: '1111111', on: true }, anonymous { user_id: '764418c2-a874-495c-b8c1-cc555ce9b202', child_id: '8c8a273f-3a84-4a66-9fa7-bb9e6c5fcf0a', reminder_id: 5, label: 'textvoice1', mode: 'textvoice', text_message: 'How you doin\'', voice_message: '1480399638', created_at: 2016-11-29T06:07:19.385Z, updated_at: 2016-11-29T06:07:19.385Z, time: '06:08', repeat: '1111111', on: true } ] 

基本上,这个工作是执行4-5倍,我不想要的。 任何帮助,将不胜感激。 谢谢。

编辑#1:我试图改变retryCount为0和增加/减lessTTL,但没有我想要的结果。

软件包的链接:

  1. Redlock
  2. 克龙

看来如果一个实例在第二个尝试获取它之前获得了锁并释放它,那么这两个实例都将运行。 你将需要一些更强大的东西。

我刚刚为node, cronivo写了一个小模块,它使用后面的js和redis,它应该为你工作,至less它可以给你一些想法。