Микросервисы и дублирующие таблицы базы данных - PullRequest
0 голосов
/ 13 мая 2018

Я работал над разделением монолитной системы (.NET) на более мелкие ограниченные контексты и, таким образом, на несколько библиотек классов.Адресные записи являются центральными для системы, поэтому для несвязанных сущностей важно обратиться к МАСТЕР-адресной записи.Каждый микросервис имеет свою собственную базу данных с таблицами, связанными с этим ограниченным контекстом.Я столкнулся с проблемой в отношении записей адресов или адресной сущности.Оба эти ограниченных контекста или библиотеки нуждаются в использовании таблицы адресов и соответствующих таблиц поиска, таких как состояние, страна и т. Д. Должен ли я дублировать таблицы, связанные с адресом, в каждой базе данных, а также дублировать классы домена, связанные с адресом?Если я дублирую, у меня будет куча дублированных записей адресов в обеих базах данных, и это застрянет.Если я помещу таблицы адресов во что-то вроде «Служба определения местоположения», будет трудно отобразить поля адреса в результатах поиска.Может быть, это неправильный сценарий для микросервисов?

ПРИМЕР: Инцидент микросервиса-1 (продукт A) -> один на один -> Адрес

Микросервис-2 (продукт B) Пожарный гидрант-> один к одному -> адрес

Микросервис-3 (продукт C) Проверка -> многие к одному -> адрес

Ответы [ 2 ]

0 голосов
/ 06 августа 2018

Для лучшей иллюстрации я предполагаю API REST для каждого микросервиса.

На мой взгляд, у вас есть IncidentService, FireHydrantService и InspectionService, которые все полагаются на LocationService.

Следуя микросервисному подходу, вы должны осознавать две цели, которые вы хотите достичь:

  • Слабая связь
  • Связное поведение

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

RESTful API великолепен, потому что мы хотим также свободно соединяться.

Ресурс может выглядеть так:

"incident": {
    "time": "...",
    "location" : {
        "name": "an arbitrary address"
        "href": "apis.yourdomain.com/locationservice/address/1"
        "type": "application/json"
    },
    "nearestHydrant": {
        "name": "hydrant 42"
        "href": "apis.yourdomain.com/firehydrantservice/hydrant/42"
        "type": "application/json"
    }
}

Как видите, эти объекты (лучше их представления) представлены только как ссылки, ссылающиеся (сущность) на ответственную службу. Эта связь является слабой, поскольку вероятность того, что ссылка будет изменена как представление сущности, в течение всего срока действия вашего приложения будет меньше. Называя поле, вы также получаете семантику отношения между FireHydrant и Incident.

Но все может сложиться очень легко. Предположим, что такое правило, как «доменный объект может быть выдан только ответственным сервисом», чтобы поддерживать связное поведение. Это означает, что только FireHydrantService разрешено обслуживать FireHydrant. Теперь представьте запрос типа «Incident по адресу 1». К какому сервису нужно обращаться за ближайшим FireHydrant? Следуя приведенному выше правилу, это должен быть FireHydrantService. Но как FireHydrantService знает, что он не знает, что означает ближайший ?

В таком случае существует вещь, называемая неавторизованным кешем (который также можно сохранить в БД). Это просто означает, что LocationService разрешено хранить FireHydrant в кеше или в базе данных, но не разрешено делиться ими с другими. Таким образом, вышеприведенное правило все еще соблюдается, а связное поведение все еще под рукой Неавторизованный кеш не должен отражать полный объект домена FireHydrant, но все необходимое для выполнения UseCases. Таким образом, IncidentService запрашивает FireHydrantService о ближайшем FireHydrant(s), что делегируется LocationService, который запрашивает в своем неавторизованном кэше ближайшее местоположение с типом FireHydrant, ответ является ссылкой (ссылка ) к самому FireHydrantService, который проверяет, имел ли FireHydrant свой Inspection и, следовательно, действителен ли он в соответствии с бизнес-правилами (если нет, проверял бы следующее) и возвращал ссылку ( Ссылка) на IncidentService.

Мое эмпирическое правило заключается в том, что каждый сервис может быть запрошен для каждого объекта домена, но может обслуживать только тот объект домена, за который он отвечает. «Запрашиваемые доменные объекты» могут находиться в вышеупомянутом неавторизованном кэше. Это, конечно, приводит к дублированию, и самое интересное - это синхронизировать их. Вещь, которая сразу приходит на ум, - это использование Event Sourcing. Служба генерирует событие «Гидрант 42 вышел из строя», а служба LocationService удаляет гидрант 42 из своего кэша.

0 голосов
/ 21 мая 2018

Поскольку я из Java, я не знаю библиотек и ограниченного контекста, связанных с .Net, упомянутых выше.Но я постараюсь ответить на этот вопрос в общем виде.Чтобы решить эту проблему, вы можете сохранить таблицы адресов в разных базах данных, к которым могут обращаться все эти три микросервиса.

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

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