Синхронная связь в основном асинхронной архитектуре микросервисов

#architecture #publish-subscribe #microservices

#архитектура #опубликовать-подписаться #микросервисы

Вопрос:

Я пытаюсь извлечь некоторые сервисы из моего любимого проекта монолитного приложения, в основном в качестве учебного упражнения. Я использую AMQP (RabbitMQ) для связи между службами, которая работает просто отлично. Однако у меня возникают проблемы с отделением веб-интерфейса от остальной части приложения. Веб-служба заботится о представлениях и логике пользовательского интерфейса, но для получения основных данных должна запрашивать серверную «основную» службу. AMQP, похоже, не подходит для этого, поскольку интерфейсной службе необходимо дождаться ответа, а время отклика имеет решающее значение. Моей первой мыслью было реализовать интерфейс REST только для этой линии связи, но тот же сервис также использует AMQP для подписки на связь других сервисов.

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

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

  • Просто используя AMQP, отправляя сообщение с reply_to полем и блокируя до получения ответа.
  • Извлеките часть доступа к данным из базовой серверной службы и предоставьте ей REST API. Тогда и веб-служба, и часть, которая «подписывается», будут запрашивать эту другую службу. Кажется ненужным иметь сервис только для доступа к базе данных.
  • Наличие нескольких потоков и использование какого-то цикла событий для прослушивания двух интерфейсов. Кажется чрезмерно сложным.

Комментарии:

1. У вас будут преимущества использования RPC и protobuf по сравнению с использованием REST для синхронной связи между службами. Кроме того, наличие двух синхронных и асинхронных коммуникаций — довольно распространенная вещь, но я не знаком с проблемой Ruby multiple threads.

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

Ответ №1:

При построении распределенной системы (SOA / Microservices) вы должны использовать модель CQS (разделение запросов команд), это может быть переведено на 2 разных канала: один для команд и событий, для изменения состояния (асинхронный обмен сообщениями), а другой для запросов, модели данных только для чтения (синхронное чтение).

После того, как вы получите эту работу, вы можете рассмотреть возможность создания моделей представлений, которые отражают бизнес-состояние ваших данных (а не ваши временные данные OLTP) с использованием комбинации pub / sub для распространения данных (не полных наборов данных, а контекстных данных, т. Е. Изменения цены продукта)

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

Имеет смысл?