Мне трудно избежать дублирования данных или общей базы данных даже для самого простого дизайна микросервисов, что заставляет меня думать, что я что-то упускаю. Вот основной пример проблемы, с которой я сталкиваюсь. Предполагая, что кто-то использует веб-приложение для управления запасами, ему понадобятся две службы; один для инвентаря, управляющего товарами и количеством на складе, и сервис для пользователей, который будет управлять данными пользователей. Если мы хотим провести аудит того, кто заполнил базу данных, мы могли бы добавить идентификатор пользователя в базу данных для службы инвентаризации в качестве последнего запаса по стоимости.
Используя приложение, мы можем захотеть увидеть все товары, которые заканчиваются, и список тех, кто их накопил в прошлый раз, чтобы мы могли попросить их пополнить его снова. Используя описанную выше архитектуру, в службу инвентаризации будет сделан запрос на получение сведений об элементах всех элементов, количество которых меньше 5. Это вернет список, включающий идентификаторы пользователей. Затем в службу пользователей будет сделан отдельный запрос на получение имени пользователя и контактных данных для списка идентификаторов пользователей, полученных из службы инвентаризации.
Это кажется ужасно неэффективным, и не требуется много дополнительных сервисов, прежде чем мы сделаем несколько запросов к API различных сервисов, которые, в свою очередь, делают несколько запросов к базе данных. Альтернативой является репликация сведений о пользователях в данных инвентаризации. Когда пользователь меняет свои контактные данные, нам нужно будет повторить изменение через все другие сервисы. Но это, похоже, не соответствует идее ограниченного контекста микросервисов. Мы также могли бы использовать одну базу данных и распределить ее между различными службами, и у нас были бы все проблемы с интеграционной базой данных .
Какой правильный / лучший способ реализовать это?
источник
Ответы:
Я полностью пропустил, где вы должны дублировать.
Главный принцип микро-услуг заключается в том, чтобы служба была единственной властью. Это означает, что инвентаризация и управление пользователями могут быть полностью разделены. Я бы спроектировал управление пользователями так, чтобы оно даже не знало, что система инвентаризации существует.
Но я бы спроектировал систему инвентаризации так, чтобы она никогда не сохраняла ничего о пользователях, кроме идентификатора пользователя. Это решает вашу проблему распространения информации о пользователях.
Что касается вещей, которые требуют как инвентарной информации, так и информации о пользователях, таких как журналы, аудиты и распечатки, они не обновляются при изменении информации. Они записи того, что было. Опять же, вы не распространяете изменения.
Таким образом, в каждом случае, когда вам нужна последняя информация о пользователе, вы спрашиваете службу информации о пользователе.
источник
It seems counter-intuitive to move from a single relational database where I could get the inventory data and the user data with a join
Имейте в виду, что «в идеале» есть один магазин на сервис (или больше!). Таким образом, нет ничего такого, как «соединение» между «границами». Причина проста, БД генерирует связь между сервисами. В отличие от предложения @CandiedOrange, я думаю, мы можем дублировать минимум данных из одного сервиса в другой. Я имею в виду данные, которые вряд ли изменятся. Если этот провал улучшит эффективность и производительность (и то, и другое обязательно), то «за», вероятно,Согласно электронной книге Microsoft по архитектуре микросервисов , нет ничего плохого в дублировании данных. По сути, дублирование данных увеличивает разделение между службами и, следовательно, усиливает их роль как единого органа. Соответствующий отрывок:
источник
Определенно да.
Конечно, в монолите у вас может быть модель инвентаризации, в которой вы запрашиваете соответствующие элементы, вводите ее в модель пользователя и получаете те же данные.
Или вы могли бы пойти дальше, если вы располагаете их в одной и той же реляционной базе данных и пишете SQL, который и база данных возьмет таблицу инвентаризации и таблицу пользователей, это делает некоторую магию, и вы получаете данные, которые вам нужны.
Независимо от того, как вы это делаете, где-то будет код, который, по сути, извлекает список идентификаторов пользователей из системы инвентаризации, передает их в систему пользователей и составляет список данных.
Вопрос, на который вам нужно ответить, касается производительности, технического обслуживания и других «мягких» качеств.
Основным преимуществом микросервисов является масштабирование. Если у вас есть десять тысяч пользователей на одной машине, и это немного вяло, вы можете добавить другую машину, и система станет в два раза быстрее. Добавьте еще восемь, и это в десять раз быстрее. (Линейное масштабирование, вероятно, является оптимистичным, но это идеал, на который можно надеяться.)
И это за услугу . Если система инвентаризации является узким местом, она используется не только для отчетов о пользователях, вы можете добавить больше машин только к этой услуге . Машины также могут быть специализированными; эта служба требует много памяти, эта служба выполняет тяжелые вычисления и требует больше ресурсов процессора.
Если вам не нужно масштабирование, есть еще одно преимущество микросервисов: они модульные . Конечно, монолитные приложения также могут быть модульными, и у вас есть нормализованная база данных и ... но на практике стены между модулями похожи на стеклянные стены в лучшем случае, а линии на песке - в худшем. Микросервисы отделены прочной сталью.
Если ваша пользовательская система буквально загорается, это никак не повлияет на вашу систему инвентаризации. Вы не сможете печатать симпатичные отчеты о том, кто на складе, но клиенты смогут безопасно размещать заказы, зная, что на складе есть товары.
И вы не дублируете данные в микросервисах , равно как и в реляционной базе данных (*). В реляционной базе данных вы можете выполнить соединение , и эквивалентно объединить списки в коде, как описано.
Вы также можете добавить представление , эквивалентное добавлению нового сервиса, который выполняет слияние для вас; это приведет к трем запросам; один к новому сервису, а затем этот сервис делает первоначальные два. В реляционных базах данных есть модные вещи, которые оптимизируют представления, которые должны быть реализованы на уровне обслуживания. Вы не получаете это "бесплатно".
Кэширование отличается от дублирования данных тем, что если два значения не совпадают, вы знаете, какое из них неправильное. Он часто используется в микросервисах для повышения доступности за счет согласованности (теорема CAP). Поскольку реляционные базы данных полностью подтверждают доступность на алтаре согласованности, они встречаются реже. Я бы сказал, что в микросервисах нет ничего, что могло бы облегчить кэширование, но на практике кэширование является основной задачей и облегчает кэширование в микросервисах .
(*) Если имеет смысл дублировать данные в микросервисном рое, то, вероятно, это будет иметь смысл в эквивалентной реляционной базе данных.
источник