Подтвердить что ты не робот

Архитектура микросервисов: совместное использование данных

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

Служба покупок отслеживает информацию о покупках пользователей.

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

Мне непонятно, как вернуть данные, которые Служба покупок не удерживает, например: полное имя пользователя. Проблема усложняется при попытке сделать более сложные вещи, такие как поиск покупок, путем покупки имени пользователя.

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

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

Как насчет реализации поиска покупок на основе имени пользователя? Я всегда могу выставить еще одну конечную точку API в конце службы пользователей, которая получает запрос, выполняет текстовый поиск по именам пользователей в службе "Пользователи", а затем возвращает все данные пользователя, соответствующие критериям. В Службе закупок сопоставьте соответствующие идентификаторы с правильными именами и покажите их на странице. Этот подход также не идеален.

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

4b9b3361

Ответ 1

Это кажется очень распространенным и центральным вопросом при переходе в микросервисы. Мне жаль, что для этого не было хорошего ответа: -)

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

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

Итак, в вашем примере у вас есть служба User для управления пользователями. Службы Покупки управляют покупками. Каждый обрабатывает свои собственные данные и только те данные, которые ему нужны (так, например, службе покупок действительно не нужно имя пользователя, а только идентификатор). И у вас есть третья услуга - Служба поиска - которая потребляет данные, созданные другими службами, и создает "просмотр" поиска из комбинированных данных.

Ответ 2

Совершенно верно для хранения соответствующих данных в разных базах данных, называемых Polyglot Persistence. Да, вы хотели бы сохранить данные пользователя и данные о покупках отдельно и использовать очередь сообщений для синхронизации. Миллионы пользователей кажутся мне прекрасными, его масштабируемость, а не проблема дизайна; -)

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

Ответ 3

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

Также подумайте, если вам нужно иметь x sub http-запросы для объединения данных в каком-то промежуточном сервисе, это приведет вас к более высокой задержке. Мы всегда стараемся сократить количество запросов для одной задачи и обрабатывать все, что возможно, через асинхронные очереди. (особенно синхронизация данных)