Можно ли совместить REST и обмен сообщениями для микросервисов? - PullRequest
1 голос
/ 11 июня 2019

У нас есть первая версия приложения, основанная на микросервисной архитектуре. Мы использовали REST для внешней и внутренней связи.

Теперь мы хотим переключиться на AP с CP (теорема CAP) * и использовать шину сообщений для связи между микросервисами. Существует много информации о том, как создать шину событий на основе Kafka, RabbitMQ и т. Д. Но я не могу найти лучшие практики для комбинации REST и обмена сообщениями. Например, вы создаете автосервис, и вам нужно добавить различные автомобильные компоненты. Для этой цели более логично использовать REST с запросами POST. С другой стороны, сервис для бронирования автомобиля будет хорошей задачей для подхода, основанного на событиях.

Есть ли у вас аналогичный подход, когда у вас есть другой словарь и возможности бизнес-логики? Как вы их объединяете? Просто поддерживать оба подхода по отдельности? Или объединить их в один подход?

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

1 Ответ

2 голосов
/ 12 июня 2019

Итог: вы ищете Командный запрос Разделение ответственности ;который определяет архитектурный шаблон для разделения обязанностей от запроса данных до запроса запускаемого процесса.Краткий ответ: вы не хотите смешивать эти два типа в запросе или процессе блокирующим образом.Остальная часть этого ответа будет подробно объяснена, почему, и тремя различными способами вы можете сделать то, что вы пытаетесь сделать.

Этот ответ является краткой формой моего опыта работы с 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 , компании, занимающейся электронной торговлей на белых этикетках.

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

...