Как обрабатывать время обработки событий между сервисами - PullRequest
0 голосов
/ 21 сентября 2019

Допустим, у нас есть две службы A и B. B имеет отношение к A, поэтому ему необходимо знать о существующих объектах A.

Служба A публикует события каждый раз, когда объект создается или обновляется.Служба B подписывается на события, публикуемые A, и поэтому знает о сущностях, существующих в службе A.

Проблема: клиент (пользовательский интерфейс или другие микроуслуги) создает новую сущность «a» и сразу же создает новуюсущность «б» со ссылкой на «а».Это делается без особых задержек, что происходит, если служба B не получила / не обработала событие от B до получения запроса на создание со ссылкой на 'b'?

Как это следует обрабатывать?

  1. Служба B должна завершиться сбоем, и клиент должен обработать это и, возможно, повторить попытку.
  2. Служба B принимает объект и со временем ожидает, что отношение будет выполнено при получении ожидаемого события.Служба B обеспечивает состояние для объекта, которое гарантирует, что ему нельзя доверять до того, как отношение было проверено.
  3. Плохой дизайн, что клиент может / должен выполнить эти два вызова в одной транзакции.Дизайн должен быть другим.Как?
  4. Другие способы?

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

Ответы [ 2 ]

1 голос
/ 23 сентября 2019

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

В вашем примере возникает вопрос о том, соответствуют ли границы обслуживания.Распространенной ошибкой является определение границ микросервиса вокруг сущностей, но это анти-паттерн.Границы микросервиса должны соответствовать границам домена , связанным с бизнес-сценарием, а не тем, как объекты моделируются в этих границах. Вот хорошая статья , в которой обсуждается разложение, но TL; DR;is:

Микросервисы должны быть глаголами, а не существительными.

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

«Правильное» решение в вашем случае зависит от потребностей потребляющего сервиса / приложения.Если потребитель является приложением или каким-либо пользовательским интерфейсом, требуется оперативность, и это становится вашей главной потребностью.Если потребителем является другой микросервис, вполне может быть, что он больше заботится о получении хороших «окончательных» данных, а не об отзывчивости.

В любом из этих случаев одним хорошим вариантом является фасад (он же шлюз) сервис, который живет между вашим клиентом и сильно зависимыми сервисами.Эта служба может получить и сохранить запрос, а затем ответить, как вы хотите.Он может дать потребителю ответ 200 - OK с конечной точкой для обратного вызова для проверки состояния запроса - очень отзывчивый.Или он может получить URL-адрес для использования в качестве веб-крюка, когда ответ будет завершен обоими внутренними службами, чтобы он мог уведомить об этом клиента напрямую.Или он может публиковать свои собственные события (вероятно, должен).По сути, вы можете адаптировать фасадный сервис, чтобы обеспечить столько потребителей, сколько необходимо, так, как каждый потребитель хочет говорить.

Есть и другие варианты.Вы можете просмотреть основанный на задачах пользовательский интерфейс , шаблон Saga или даже просто Faking It .

0 голосов
/ 21 сентября 2019

Я думаю, вы хотели бы использовать гибкость брокера и подтверждение синхронного вызова.Оба они могут быть достигнуты этим

https://www.rabbitmq.com/tutorials/tutorial-six-dotnet.html

...