Как стать автором
Обновить

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

логично сделать не через явный вызов внешних сервисов, а в сервисе регистрации положить в очередь сообщение “пользователь 123 зарегистрирован”, а все нужные сервисы прочитают это сообщения и совершат необходимое действие

И как это реализуется технически? Просто очередь тут, очевидно, не сработает, так как нет контроля над количеством чтений. Pubsub? Возможно, но тогда возможен отказ в обслуживании, если подписчики заняты.

Topic vs Queue

Про отказ в обслуживании — важные действия, обычно, делают синхронными. Либо если асинхронными, то процесс делают таким, чтобы следить за таймаутами, и идти по альтернативе, если ошибка таймаута. В общем все в руках проектировщика.
например Apache Kafka создана для решения этой задачи
а каким образом кафка гарантирует, что сообщение прочли все? Насколько я помню, у кафки таких гарантий нет, есть только гарантия того, что сообщение будет доступно для всех, кто пожелает.
Одним из способов развязать куски кода может служить организация взаимодействия между сервисами через очередь сообщений.


как ты их не развязывай, все равно остаются кейсы синхронного взаимодействия между сервисами. Банально необходимость получения ответа, а в очередях сообщений это целый велосипед зачастую и в итоге мы получаем систему с двумя типами коммуникации, которые надо поддерживать
queue correlation id

Request-Response вполне себе события.

Не совсем про микросервисы, а про REST и «чистоту расы», коммент.
Если есть необходимость выполнения бизнес-действий (а они как правило есть) над данными (которыми оперирует REST), то есть смысл вводить понятие задач. Задачами являются бизнес-действия (возможно длительные), которые представлены в REST существительными, а не глаголами. Т.е. не надо в URL пихать глаголы.

Например:
Создаем задачу:
POST /api/v1/tickets/{ticketid}/tasks
{'action': 'migrate', ...params}
В ответ получаем модель задачи и если ее статус не завершен, то через некоторое время делаем так:
GET /api/v1/tickets/{ticketid}/tasks/{taskid}

Можем отменить задачу
DELETE /api/v1/tickets/{ticketid}/tasks/{taskid}

Если выполнение задачи еще не началось, то можно разрешить изменение ее параметров
PUT /api/v1/tickets/{ticketid}/tasks/{taskid}

Итого: Можно и REST сохранить, и бизнес-действия выполнить, и за чистоту расы не бояться.

Это если нужно сохранять rest. Часто объяснить не могут, а почему, собственно, rest.

Да, прежде чем использовать REST, надо понять зачем это. Серебряной пули нет. Но если уж говорит что у вас есть REST API, то надо чтобы оно было REST, а не помесью непонятно чего с непонятно чем.

В подавляющем большинстве случае REST API таковым не является. Хотя бы из-за отсуствия поддержки HATEOAS

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

Мне показалось, что автор интуитивно подводит к понятию предметно-ориентированного проектирования.
Разве лучший способ декомпозиции микросервисов не ограниченный контекст?

Не всегда он лучший. Но в целом, да, хорошо выделенный контекст хороший кандидат на вынесение в ммкросервис

Отличная статья! Большинство статей про сервисную архитектуру, что я видел на хабре, сводятся к низкоуровневым темам в зоне devops. А про высокоуровневое проектирование эта лучшая статья что я видел здесь.
Сервис-сущность как антипаттерн

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

Кажется, что решить эту проблему можно, если сделать над сервисами-сущностями отдельный “слой” сервис, которые инкапсулируют в себя всю логику. Но обычно это тоже плохо заканчивается. Потому что тогда сервисы-сущности становятся сервисами-хранилищами, т.е. вся бизнес-логика из них вымывается, кроме хранения.

Этот отдельный слой называется хореограф или оркестратор, паттерн типа Саги и т.д. Все верно, его задача — реализовывать бизнес-логику и манипулировать данными из микросервисов-хранилищ (забирая из через API). Что в этом автор увидел плохого, непонятно.

Пример. Для менеджера, который работает с наполнением товарной номенклатуры, главными фичами будут возможность удобно добавлять товар, удалять, менять и просматривать. Нагрузки немного, если разделить в отдельные сервисы чтение и изменение, мы от такого разделения ничего не получим, кроме проблем, когда придется делать в сервисах согласованные изменения.

А зачем в данном примере что-то разделять? CQRS надо использовать только там, где это необходимо.
В документациях по микросервисной архитектуре для сложных сущностей рекомендуют делать микросервисы-витрины, которые агрегируют данные из микросервисов-сущностей и предоставляют их потребителям.


Если эти сервисы-сущности используются только в микросервисе витрине, то зачем они вообще нужны? Не проще ли будет сразу ходить в БД?

Если используют другие сервисы, то там будут собираться методы, которые нужны разным бизнес-процессам. И чтобы сделать изменения в сервисе — надо все-равно ходить и смотреть как в других сервисах используется — какие на самом деле есть ограничения и инварианты на сущность.

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

Если интересно, что по этому поводу считают люди в целом по индустрии, то Фаулер тоже считает сервис-сущность антипаттерном, например.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации