我想每分钟运行一次任务,为此我选择了cron。现在,我使用集群模块运行节点,它生成了4个进程,但我希望每分钟只在每个进程上运行cron一次。
现在,解决这个问题的一个解决方案是在master中运行它。但是,如果我在每个实例上启动多个带有集群的实例,这将于事无补。
所以我决定寻找锁定机制。我找到了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并增加/减少TTL,但没有得到我想要的结果。
与软件包的链接:
发布于 2016-12-07 18:34:38
看起来,如果一个实例在第二个实例尝试获取锁之前获得并释放了它,那么这两个实例都将运行。你需要一些更健壮的东西。
我刚刚为节点编写了一个小模块,克罗尼沃,它使用了后置just和redis,它应该适合您,至少它可以给您一些想法。
https://stackoverflow.com/questions/40860371
复制相似问题