Итог: вы ищете Командный запрос Разделение ответственности ;который определяет архитектурный шаблон для разделения обязанностей от запроса данных до запроса запускаемого процесса.Краткий ответ: вы не хотите смешивать эти два типа в запросе или процессе блокирующим образом.Остальная часть этого ответа будет подробно объяснена, почему, и тремя различными способами вы можете сделать то, что вы пытаетесь сделать.
Этот ответ является краткой формой моего опыта работы с Microservices.Мои добрые намерения: я создал топологии Microservices с нуля (и почти без знаний) и, как говорится, попал в каждую ветку на пути вниз.
Одним из преимуществ начала с нуля является то, что в первой созданной мною топологии использовалась смесь внутрисервисного синхронного и блокирующего (HTTP) обмена данными (для извлечения данных, необходимых для операции, из службы, которая удерживалаit) и очереди сообщений + асинхронные события для запуска операций (для команд).
Я определю оба термина:
Команды : указание службе что-либо делать,Например, «Выполнить пакетное задание ETL».Вы ожидаете, что будет выход из этого;но это процесс, от которого вы не сможете надежно ждать.У команды есть побочные эффекты.Из-за этого действия что-то изменится (если ничего не происходит и ничего не меняется, значит, вы ничего не сделали).
Запрос : Запрос службы для данных, которые она содержит.Эти данные могли быть там из-за данной команды, но запрос данных не должен иметь побочных эффектов .Никакие командные операции не должны требовать для запуска из-за полученного запроса.
В любом случае, вернемся к топологии.
Уровень 1: Смешанный HTTP и события
Для этой первой топологии мы смешали синхронные запросы с генерируемыми асинхронными событиями.Это было ... проблематично.
Сообщение Автобусы по своей природе наблюдаемы.Один параметр в RabbitMQ или Источник событий, и вы можете наблюдать за всеми событиями в системе.Это имеет некоторые хорошие побочные эффекты в том, что когда что-то происходит в процессе, вы обычно можете выяснить, какие события привели к этому состоянию (если вы следуете управляемой событиями парадигме + конечные автоматы).
HTTP-вызовы не наблюдаются без проверки сетевого трафика или регистрации этих запросов (что само по себе имеет проблемы, поэтому мы начнем с "неосуществимых" в обычных операциях).Поэтому, если вы смешаете процесс, основанный на сообщениях, и HTTP-вызовы, у вас будут дыры, в которых вы не сможете сказать, что происходит.У вас будут места, где из-за сетевой ошибки ваш HTTP-вызов не вернул данные, и ваши службы не продолжили процесс из-за этого.Вам также нужно будет подключить шаблоны Retry / Circuit Breaker для ваших HTTP-вызовов, чтобы убедиться, что они хотя бы несколько раз попробуют, но тогда вам придется различать «Не вверх, потому что он выключен», и «Не вверх, потому что он временно занят»".
Короче говоря, смешивание двух методов для процесса, управляемого с помощью команд, не очень устойчиво.
Уровень 2. События определяют RPC / внутренний запрос / ответ для данных;Внешние запросы
На втором шаге этой модели зрелости вы отделяете Команды и Запросы.Команды должны использовать управляемую событиями систему, а запросы должны выполняться через HTTP.Если вам нужны результаты запроса для команды, вы создаете сообщение и используете шаблон запроса / ответа по шине сообщений.
Это также имеет свои преимущества и проблемы.
Преимущества по всей вашей Команде теперь наблюдаемы, даже если она перепрыгивает через несколько служб.Вы также можете воспроизводить процессы в системе, перезапуская события, которые могут быть полезны для отслеживания проблем.
Теперь некоторые ваши события выглядят как запросы;и теперь вы воссоздаете прекрасную семантику HTTP и REST, доступную в HTTP для сообщений;и это не очень весело или полезно.Например, 404 сообщает, что в REST нет данных.Для событий, основанных на сообщениях, вы должны воссоздать эту семантику (есть хорошая беседа на Youtube на эту тему, которую я не могу найти, но команда попыталась сделать это с большой болью).
Однако ваши событиятеперь асинхронные и неблокирующие, и каждая служба может быть реорганизована в конечный автомат, который будет реагировать на данное событие.Некоторые предостережения в том, что эти события должны содержать все данные, необходимые для операции (что приводит к росту количества сообщений в ходе процесса).
Ваши запросы все еще могут использовать HTTP для внешней связи;но для внутренних команд / процессов вы бы использовали шину сообщений.
Я также не рекомендую этот подход (хотя это шаг по сравнению с первым подходом).Я не рекомендую это из-за нечистоты, которую начинают воспринимать ваши события, и в системе микросервисов, имеющих контракты, одинаковые для всей системы, важно.
Уровень 3: Производители данных испускают данные как события.Потребители записывают данные для их использования.
Третий шаг в модели зрелости (и мы были на пути к этой парадигме, когда я уходил из проекта) - для служб, которые генерируют данные для выдачи событий, когда эти данныепроизводится.Затем эти данные записываются службами, прослушивающими эти события, и эти службы будут использовать эти (могут быть?) Устаревшие данные для выполнения своих операций.Внешние клиенты все еще используют HTTP;но внутренне вы генерируете события, когда создаются новые данные, и каждая служба, которая заботится об этих данных, будет хранить их для использования в случае необходимости.В этом суть выступления Майкла Брайзека Проектирование архитектуры микросервисов в правильном направлении .Майкл Брайзек - технический директор Flow.io , компании, занимающейся электронной торговлей на белых этикетках.
Если вы хотите получить более глубокий ответ наряду с другими проблемами, я укажу на мой пост в блоге на эту тему .