Как выполнять периодические задачи в системе, построенной с использованием подхода CQRS?
Оказалось, что в моей системе должны быть периодические задачи, выполняемые под рабочей ролью Windows Azure. Хочу подчеркнуть, что это может быть любая платформа Azure, Amazon, собственное решение. С точки зрения обычной системы вопрос не в том, как выполнить задачу, но, поскольку мы находимся в облаке, и может быть несколько случаев моей роли, это может быть проблемой в какой-то момент.
Вот пара подходов, о которых я могу подумать:
Обычные таймеры, которые синхронизируются, скажем, через хранилище Azure, чтобы не запускать задачу несколько раз. Вы можете реализовать это самостоятельно или взять, например, у Lokad. Вы можете выполнить свою задачу на встроенном таймере или отправить команду в очередь.
Плюсы:
- Общий подход, все знают таймеры и как их готовить
- Не нужно иметь государство. Как только ваши экземпляры запущены, таймеры также работают
Минусы:
- Существует дополнительная логика инициализации таймеров и их запуска рядом с основной частью, которая отвечает только за обработку команд и событий из очереди.
Как только я получил команду на запуск задачи, я посылаю команду 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. Таким образом, каждый рабочий процесс может проверить этот график.