2016-11-29 4 views
1

Я хочу запускать задачу каждую минуту, и для этого я выбрал cron. Теперь я запускаю узел с использованием кластерного модуля, и он порождает 4 процесса, но я хочу запускать cron только один раз за процесс в минуту.Использование cron с redlock и cluster в nodejs

Теперь одно из решений - запустить его в мастер. Но это не поможет, если я запускаю более одного экземпляра с кластером для каждого экземпляра.

Так что я решил искать блокирующие механизмы. Я нашел 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 раз, которые я do't хочу. Любая помощь будет оценена по достоинству. Благодарю.

EDIT # 1: Я попытался изменить retryCount на 0 и увеличить/уменьшить TTL, но не получил результатов, которые я хочу.

Ссылки на пакеты:

  1. Redlock
  2. Cron

ответ

1

кажется, что если экземпляр получает блокировку и освобождает его перед тем, как второй один пытается получить его, как будет работать. Вам понадобится нечто более надежное.

Я написал небольшой модуль для узла, cronivo, он использует laterJs и redis, и он должен работать на вас, по крайней мере, он может дать вам некоторые идеи.

+0

Я нашел альтернативный путь. Я не вручную отпираю замок и только в зависимости от TTL для блокировки. Таким образом, до сих пор я не сталкивался с какими-либо проблемами. Можете ли вы сказать мне, возможны ли какие-либо проблемы? –

+0

Если экземпляр занят и завершает попытку выполнить после TTL, он будет выполняться, даже если он не должен. Если ваш TTL достаточно велик, это очень маловероятно. Я не думаю, что этот подход очень хорош, но он может работать. –

+0

Я не против запуска другого процесса, но я не хочу, чтобы работа выполнялась дважды или трижды .... мой ttl составляет 60 секунд ... Я хочу каждую минуту проверять, какие напоминания нужно отправить. Так что если в 06:11 процесс получает напоминания за 06:11, то в 06:12 я хочу напоминания для 06:12. То, что я не хочу, это 4 процесса получения напоминаний на 06:11, потому что тогда они будут отправлены 4 раза. –

Смежные вопросы