Как выполнять периодические задачи в системе, построенной с использованием подхода CQRS?

Оказалось, что в моей системе должны быть периодические задачи, выполняемые под рабочей ролью Windows Azure. Хочу подчеркнуть, что это может быть любая платформа Azure, Amazon, собственное решение. С точки зрения обычной системы вопрос не в том, как выполнить задачу, но, поскольку мы находимся в облаке, и может быть несколько случаев моей роли, это может быть проблемой в какой-то момент.

Вот пара подходов, о которых я могу подумать:

  1. Обычные таймеры, которые синхронизируются, скажем, через хранилище Azure, чтобы не запускать задачу несколько раз. Вы можете реализовать это самостоятельно или взять, например, у Lokad. Вы можете выполнить свою задачу на встроенном таймере или отправить команду в очередь.

    Плюсы:

    • Общий подход, все знают таймеры и как их готовить
    • Не нужно иметь государство. Как только ваши экземпляры запущены, таймеры также работают

    Минусы:

    • Существует дополнительная логика инициализации таймеров и их запуска рядом с основной частью, которая отвечает только за обработку команд и событий из очереди.

  2. Как только я получил команду на запуск задачи, я посылаю команду StartTask(30 секунд). После того, как обработчик команды получил его, он выполняет все, что нужно, и затем повторно отбрасывает ту же команду с задержкой в ​​30 секунд.

    Плюсы:

    • Идеально подходит для дизайна CQRS
    • Никакой дополнительной логики, связанной с таймерами, чистый реактор

    Минусы:

    • Нарушение парадигмы, сам CQRS действительно трудно лечить и использовать с самого начала. Люди склонны использовать известные технологии (обычные таймеры), даже если они не соответствуют дизайну (подход cqrs), и в результате мы получаем беспорядочный синтез.
    • Еще одна сломанная парадигма. Это состояние без сохранения состояния или перезапуск системы? Я бы сказал, что состояние хранится в среде обмена сообщениями. Все, что вам нужно сделать, это следовать правилам обработки сообщений.

Мое мнение по этому поводу:

Лично я предпочитаю второй подход, и все минусы из него следует перенести в плюсы.

Вопрос:

Какова лучшая практика здесь? Я что-то пропустил?

4 ответа

Решение

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

Если вы предпочитаете, чтобы один экземпляр обрабатывал обе эти задачи (периодические и CQRS) в Azure, вы можете преобразовать их в службы Windows и использовать свою рабочую роль в качестве установщика и наблюдателя. У меня есть пример, построенный с моим решением здесь.

Кстати, если вы используете Lokad.Cqrs, тогда ваш второй подход звучит хорошо, если он отделен от основного компонента.

Если вы используете Azure Servicebus в качестве своего брокера, вы можете использовать его функцию отложенных сообщений, чтобы отложить отправку вашей команды до времени, когда она должна быть получена. http://code.msdn.microsoft.com/windowsazure/Brokered-Messaging-ccc4f879

Как насчет использования планировщика из служб Windows Mobile или приложения планировщика Магазина Windows Azure от Aditi? Они могут использоваться для запуска чего угодно, и вы можете заставить их отправить команду в вашу систему.

Если вы сделали вариант 1, то да, вам придется иметь дело с синхронизацией, но там есть встроенная избыточность. Если вы выполнили опцию 2 и экземпляр, обрабатывающий команду, вышел из строя, убедитесь, что задачи не просто остановились. Это будет зависеть от того, как настроены ваши повторные команды.

Прошедшее запланированное время - это событие, поэтому у меня будет процесс, который создает события, подобные "ScheduleElapsedEvent". Затем вы можете реализовать обработчики, которые при необходимости создают / отправляют команды.

Вы можете хранить расписания событий в хранилище данных, которое поддерживает какие-то атомарные обновления. Это может быть SQL или NoSQL, например MongoDB. Даже если вы масштабируете наборы реплик и осколки, вы все равно можете проверять и обновлять запись с помощью Mongo. Таким образом, каждый рабочий процесс может проверить этот график.

Другие вопросы по тегам