Возможно, одним из самых сложных шаблонов микросервисов для применения и реализации является ограниченный контекст.
Концепция ограниченного контекста зародилась в кругах, основанных на доменном дизайне (DDD). Он продвигает объектно-ориентированный подход к сервису, определяя модель данных, за которую сервис отвечает и с которой «связан». Другими словами, служба владеет этими данными и отвечает за их целостность и изменчивость. Это поддерживает важные функции микросервисов независимости и развязки.
Это имеет смысл на бумаге. Кроме того, реализация ограниченного контекста для реализации нового проекта не так сложна, поскольку зачастую устаревший источник данных может не существовать.
Но чтобы понять шаблон ограниченного контекста и трудности, с которыми можно столкнуться во время реализации этого шаблона, рассмотрим устаревшее или традиционное приложение. Часто устаревшее приложение поддерживается одной базой данных, и эта база данных, вероятно, поддерживает несколько приложений или даже другую систему приложений записи. Типичный пример изображен ниже:
В стиле разработки Microservices приложение состоит из независимых сервисов компонента времени выполнения, которые реализуют некоторую функцию приложения. Это контрастирует с одним монолитным компонентом времени выполнения.
Чтобы сохранить эти сервисы независимыми (т. Е. С возможностью их изменения и перемещения в среду выполнения и из нее без побочных эффектов для других сервисов), источник данных, поддерживающий эти сервисы, также должен быть независимым. Здесь вступает в силу шаблон ограниченного контекста.
Приложение Microservices может выглядеть следующим образом:
Введение базы данных для каждой службы обычно приводит к сумасшествию администратора баз данных. Это понятно, поскольку администраторы баз данных, как правило, пытаются создать единый источник корпоративной структуры данных истины, и внезапно они думают, что им придется столкнуться с необходимостью поддержки взрыва экземпляров базы данных. Если бы эти корпоративные базы данных были основаны на NoSQL, это могло бы быть не так уж плохо; но большинство из них основаны на реляционных принципах, что обеспечивает надежную целостность данных, поддержку транзакций и множество способов нарезки, нарезки и представления данных. Таким образом, подчеркнутый ответ DBA понятен.
Цель этого поста — предоставить вам некоторую информацию о том, как реализовать ограниченный контекст таким образом, чтобы облегчить беспокойство администратора баз данных.
Вам не нужно принимать DB-Per-Service буквально
Скажем, что вам нужно применять ограниченный контекст для реализации вашего сервиса. Скажем также, у вас есть существующая реляционная база данных предприятия и традиционная юридическая организация Конвея с командой DBA. В этом сценарии, вот несколько вариантов, которые могут работать вместо создания базы данных для каждого экземпляра.
Что такое закон Конвея?
Закон Конвея — это поговорка, названная в честь программиста Мелвина Конвея, который представил эту идею в 1967 году.
Таким образом, структура программных интерфейсов системы будет отражать социальные границы организации (организаций), которая ее произвела, и через которую коммуникация является более сложной.
Цель состоит в том, чтобы требовать от приложений доступа к постоянному хранилищу данных через API, предоставляемый реализацией службы.
Безопасность на основе таблиц
Права защищенного доступа применяются на табличной основе. Таблицы в ограниченном контексте службы получают права на чтение / запись / удаление, в противном случае они не могут получить доступ к таблицам в других службах. Учетная запись пользователя службы может быть создана для каждой службы и примененных привилегий.
Безопасность на основе схемы
Каждой службе может быть создана схема базы данных и назначены авторизованные роли учетной записи службы.
Псевдо Честь Система безопасности
Использование обзоров кода и / или применение некоторых метаданных, таких как аннотации JPA, к вашему коду для системы сборки, чтобы найти и сравнить с каким-то манифестом, который определяет таблицы, принадлежащие сервисам, и сообщать о нарушениях.
Возможная последовательность и транзакции
Поскольку платформа Microservice является распределенной вычислительной средой, возможная последовательность — это поведение, которое сопровождает ее. Транзакция на основе ACID в среде распределенных микросервисов может быть сложной. Поскольку источник данных приложения будет распределен по службам, данные вашего приложения, возможно, придется терпеть в конечном итоге согласованность. Обмен от ACID для терпимой задержки. Многие приложения являются типичными: поиск чего-либо, добавление чего-либо, удаление чего-либо, или, может быть, расчет или два. Эти типы приложений могут существовать в возможной согласованной среде. Однако если требуется доступ в режиме реального времени или ACID-совместимые транзакции, то границы API сервиса могут потребоваться для соблюдения этих границ транзакции.
Что такое КИСЛОТА?
В области компьютерных наук ACID (атомарность, согласованность, изоляция, долговечность) — это набор свойств, гарантирующих надежную обработку транзакций в базе данных. Например, перевод средств с одного банковского счета на другой, даже с несколькими изменениями, такими как дебетование одного счета и зачисление на другой, представляет собой одну транзакцию.
Источник: https://en.wikipedia.org/wiki/ACID
Обработка иностранных ключей
Ссылочная целостность — это функция, предоставляемая реляционными базами данных, которая должна применяться к таблицам и ограничениям отношений в ограниченном контексте.
Однако рассмотрим следующую объектную модель обслуживания проекта, отвечающую за управление (т. Е. CRUD) проектами и ресурсы для проектов.
Обратите внимание, что объект Employee помечен как не в контексте. Это связано с тем, что объекты Employee являются частью службы Employee и ее ограниченного контекста, поэтому их следует вводить в службу Project. Предполагая, что объектные модели сопоставлены с реляционным источником данных, вместо того, чтобы Служба проекта могла сопоставлять тип Сотрудника, она имеет только внешний ключ для сотрудника. Диаграмма показывает эту концепцию ниже:
Базовая сопоставленная таблица для модели ProjectResource будет иметь только внешний ключ для сотрудника и не материализует объект Employee из базы данных. Чтобы получить или изменить мувика сотрудника, вы будете использовать вызовы API службы сотрудника.
В этом примере концептуально применяется ограниченный контекст, предотвращающий сопоставление службы проекта с элементами данных сотрудника. Это может быть физически обеспечено физическими границами базы данных или ранее упомянутыми механизмами безопасности базы данных. Тем не менее, есть еще несколько механизмов, которые необходимо внедрить для поддержки этой изоляции. В частности, когда сотрудник удаляется через службу сотрудника, как другие службы информируют об этом удалении? Объединение службы сотрудника синхронно с другими службами, заинтересованными в сотруднике, было бы сопряжено. Асинхронный обмен сообщениями обеспечивает связь без связи.
Использование надежной, устойчивой системы обмена сообщениями, такой как ZooKeeper / Kafka (или что-то подобное), предоставляет способ для достижения этой цели. Kafka имеет постоянный механизм ведения журнала и будет воспроизводить историю сообщений о событиях для потребителей, если они недоступны, когда издатель вызывает событие сообщения. Это поддерживает независимость микросервисной платформы с услугами, входящими и выходящими на временной основе.
Обобщенные сообщения и соглашения могут быть установлены в ваших реализациях сервиса. Когда какой-либо сервис выполняет операцию создания, чтения, обновления или удаления (CRUD), он может вызвать событие, которое отражает первичный ключ, операцию, пользователя и, возможно, дату / время события.
Вот частичный пример реализации, которая выполняет CRUD для службы Employee и вызывает событие для потребителей:
01
02
03
04
05
06
07
08
09
10
|
public class EmployeeService { …. public void delete(Employee employee) { repository.delete(employee); // produce delete topic KafkaHelper.produceTopic(“employee.delete”, employee.getId(), CurrentUser.getId(), Calendar.getInstance() ); } ….. } |
Потребительские службы, такие как Служба проекта, должны знать, когда сотрудник удален, чтобы он мог обновить Ресурсы своего Проекта, другими словами, сотрудник, назначенный проекту, больше не существует. Служба проекта может прослушать эту тему мероприятия в Какфе, опубликованную службой служащих, и реагировать соответствующим образом.
Вот пример потребителя обработчика Kafka Topic, который предоставляет блок кода для удаления ресурса проекта при удалении Employee. Этот код будет выполнен после запуска приложения.
Вот интерфейс блока кода, который использует помощник KafkaConsumer:
1
2
3
4
5
|
// Kafka Topic Execution Block public interface Block { public void execute(MessageAndMetadata<byte[], byte[]> mmd); } |
Этот метод инициализирует потребителей для прослушивания опубликованных тем и связывает исполняемый блок кода для выполнения при возникновении:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
public class TopicConsumerss { @Autowired private ProjectService service; @PostConstruct public void init() { Block empDeleteBlock = new Block() { public void execute(MessageAndMetadata<byte[], byte[]> mmd) { // get id from topic msg, could be cleaner, but you get the jist... String msg = new String(mmd.message()); String id = msg. split ( ":" )[1]; service.service.deleteForEmployeeId(new Long( id )); } }; KafkaHelper.consume(“employee.delete”, empDeleteBlock ); } } |
Этот механизм позволяет службам прослушивать и реагировать на события базы данных, такие как обновление или добавление к событиям, без необходимости непосредственного вызова служб, заинтересованных в этих операциях.
Примером может служить служба аудита, которая может собирать и записывать операции базы данных для отчетов и запросов аудита, как показано на диаграмме ниже.
Вывод
В традиционном монолитном приложении вся объектная модель приложения управляется и отображается в одну базу данных. Информация аудита, ограничения внешнего ключа и каскадные операции CRUD обрабатываются единой базой данных.
Однако в среде Microservices с ограниченным контекстом каждая служба может поддерживаться или не поддерживаться одной и той же единой базой данных. В этом сценарии обобщенный механизм асинхронного обмена сообщениями может обеспечить поддержку распределенной среды.
Ресурс
- Мартин Фаулер об ограниченном контексте — http://martinfowler.com/bliki/BoundedContext.html
Ссылка: | Внедрение ограниченного контекста от нашего партнера JCG Дэвида Питта в блоге |