Где должна лежать бизнес-логика в микросервисной архитектуре?

12

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

Предположим, мы пытаемся создать чрезвычайно упрощенную систему бронирования Uber. Чтобы упростить, скажем , у нас есть 3 услуги и API шлюза для клиента: Booking, Drivers, Notificationи мы имеем следующий рабочий процесс:

При создании нового бронирования:

  1. Проверьте, есть ли у уже существующего пользователя бронирование
  2. Получить список доступных драйверов
  3. Отправьте уведомление водителям, чтобы забрать заказ
  4. Водитель забирает бронирование

Допустим, весь обмен сообщениями осуществляется через http-вызов, а не через шину обмена сообщениями, такую ​​как kafka, для простоты.

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

  • Gateway - получить список доступных драйверов + отправить уведомления
  • Booking - проверить наличие бронирования

И я почти уверен, что шлюз не подходящее место для этого, но я чувствую, что если мы делаем это в Bookingсервисе, он становится тесно связанным?

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

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

GantengX
источник
2
Это действительно трудно ответить без всего контекста. И даже зная это, начинать проект по распространению бизнес-логики на микроуслуги не всегда хорошая идея, и именно поэтому некоторые люди принимают «Монолит первый», потому что в начале вы действительно не знаете обязанностей каждой части ваше приложение. Это станет ясно только позже.
Дерик,

Ответы:

14

Люди часто слышат «микро-сервис» и думают «нано-сервис», и это может вызвать путаницу. Это микро- сервисы, поэтому вам не нужен отдельный сервис для каждого отдельного объекта. Все, что вы пытаетесь сделать, должно быть в bookingи notificationсервисах. Вам не нужна driverуслуга (для любого из действий, которые вы описали).

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

Теперь, что касается повторного использования, преимущество наличия отдельного микросервиса состоит в том, что теперь у вас может быть три отдельных команды, создающих приложения для потребителей. Одна команда для стандартного веб-приложения html, приложения для Android и приложения для iOS. Все эти разные приложения могут быть построены совершенно по-разному и выглядят подходящими для их конкретной платформы (без повторения кода). Код bookingслужбы повторно используется всеми тремя этими приложениями, поскольку все три приложения выполняют http-вызовы службы, вместо этого имея собственный код бронирования.

Типичный поток бронирования будет выглядеть так:

  1. Приложение для Android вызывает bookingсервис, чтобы получить список доступных драйверов
  2. Служба бронирования возвращает список водителей в приложение
  3. Затем пользователь выбирает свой драйвер, а приложение вызывает метод bookingсервиса «книга».
  4. bookingОбслуживание вызывает notificationслужбу с деталями бронирования
  5. notificationСлужба отправляет уведомление водителя, сообщив ему о бронировании
  6. Приложение драйвера отправляет сообщение в notificationслужбу, когда они находятся в миле от клиента
  7. notificationСлужба отправляет уведомление клиенту , что их водитель почти нет

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

TheCatWhisperer
источник
1

Все зависит от ваших точных требований.

Допустим, у вас есть две заявки на бронирование:

  1. Первый случай: одно приложение может разрешить одному пользователю бронировать несколько раз, другое - только одно. Это означает, что ограничение бронирования находится на уровне приложения, поэтому у вас есть две точки входа в систему бронирования (одна, которая допускает многократное бронирование, другая - нет), или вы просто проверяете это в микросервисах соответствующего применение.
  2. Второй случай: это часть определения «Бронирование», что у пользователя не может быть нескольких приложений независимо от приложения. Это правило верно для всей системы: это означает, что вы можете поставить чек в микросервисе бронирования.

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

Единственная проблема в архитектуре такого типа заключается в том, что происходит, если после публикации уведомления происходит сбой, так как два микросервиса не работают как две функции, выполняющиеся в одной и той же транзакции базы данных, вам нужно будет корректно обрабатывать ошибки и в конечном итоге воспроизводить процессы которые потерпели неудачу (автоматически или вручную)

Walfrat
источник
0

Ответ прост: клиенты микросервисов управляют бизнес-логикой в ​​«чистой» архитектуре микросервисов. Чтобы было легче понять, рассмотрим еще более простой пример. Служба, которая просто возвращает потоки байтов на основе URI. Само по себе это не очень полезно. Без какого-либо способа узнать, какие URI есть, что в них, вы можете только догадываться, куда вытащить вещи. Теперь предположим, что у вас есть другой микросервис, который предоставляет возможность поиска. Вы отправляете запрос со строкой запроса, и он возвращает URI. Теперь все становится интереснее. Я могу поместить ссылки на URI для первой службы в индекс.

Но все же, нам нужно как-то координировать эти два. Ответ прост: вы используете браузер для получения URI из службы индексирования, а затем извлекаете данные из службы данных. Ни одна служба не «знает» о другой, и между ними нет абсолютно никакой связи. Я могу использовать службу индексации с любой другой службой данных и наоборот.

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

JimmyJames
источник