Определение границ микрослужб

Azure DevOps

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

Схема ограниченных контекстов.

В этой статье в качестве примера используется служба доставки с помощью дронов. Дополнительные сведения о сценарии и соответствующей эталонной реализации см. здесь.

От модели предметной области к микрослужбам

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

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

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

  2. Затем проанализируйте статистические выражения в модели предметной области. Статистические выражения часто являются хорошими кандидатами для микрослужбы. Хорошо спроектированные статистические выражения демонстрируют характеристики хорошо спроектированной микрослужбы, например:

    • Статистические выражения скорее происходят из бизнес-требований, нежели из технических соображений, таких как доступ к данным или обмен сообщениями.
    • Статистические выражения должны иметь высокую функциональную слаженность.
    • Статистическое выражение является границей сохраняемости.
    • Статистические выражения должны быть слабо связаны.
  3. Службы предметных областей также являются хорошими кандидатами для микрослужб. Службы предметных областей — это операции без отслеживания состояния в нескольких статистических выражениях. Типичным примером является рабочий процесс, включающий несколько микрослужб. Мы увидим пример такого процесса в приложении доставки помощью дронов.

  4. Наконец, рассмотрим нефункциональные требования. Рассмотрите такие факторы, как размер команды, тип данных, технологии, требования к масштабируемости, доступности и безопасности. Возможно, из-за них вам придется разделить микрослужбу на две или более меньшие службы или сделать противоположное (объединить несколько микрослужб в одну).

Когда вы определите микрослужбы в приложении, поверьте структуру на соответствие следующим условиям:

  • Каждая из служб отвечает за одну функциональность.
  • Между службами отсутствуют частые вызовы. Если после разделения функциональности на две службы они станут отправлять слишком много вызовов, это может быть признаком того, что функции принадлежат к одной службе.
  • Каждая из служб достаточно небольшая, так что ее может независимо создать команда из нескольких человек.
  • Нет никаких взаимных зависимостей, из-за которых необходимо развертывать две или больше микрослужб в связке. Всегда должна быть возможность развернуть службу без повторного развертывания других служб.
  • Службы не имеют тесной связи и могут развиваться независимо.
  • Границы вашей службы не будут создавать проблем с согласованностью или целостностью данных. Иногда важно поддерживать согласованность данных, разместив функциональность в одной микрослужбе. Тем не менее, подумайте, действительно ли вам нужна высокая согласованность. Существуют стратегии для обеспечения итоговой согласованности в распределенной системе, а преимущества декомпозиции служб часто перевешивают проблемы поддержки такой согласованности.

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

Пример. Определение микрослужб для приложения доставки с помощью дронов

Помните, что группа разработчиков определила четыре агрегата — Доставка, Пакет, Дрон и Учетная запись — и две доменные службы, Планировщик и Руководитель.

"Доставка" и "Посылка" являются очевидными кандидатами для микрослужб. "Планировщик" и "Контролер" координируют действия, выполняемые другими микрослужбами, поэтому имеет смысл внедрить эти службы предметных областей в качестве микрослужб.

"Дрон" и "Учетная запись" интересны тем, что они принадлежат к другим ограниченным контекстам. Один из вариантов заключается в том, чтобы "Планировщик" напрямую вызывал ограниченные контексты "Дрон" и "Учетная запись". Также можно создать микрослужбы"Дрон" и "Учетная запись" внутри ограниченного контекста доставки. Эти микрослужбы будут посредниками между ограниченными контекстами, предоставляя API или схемы данных, которые более подходят для контекста доставки.

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

  • Какова нагрузка на сеть для прямого вызова другого ограниченного контекста?

  • Подходит ли схема данных другого ограниченного контекста для этого контекста или лучше иметь схему, предназначенную для этого ограниченного контекста?

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

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

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

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

На следующей схеме показана структура на этом конкретном этапе:

Схема, демонстрирующая структуру микрослужб для приложения доставки дронами.

Скачайте файл Visio этой архитектуры.

Дальнейшие действия

На этом этапе вы должны иметь четкое представление о назначении и функциональности каждой микрослужбы в вашем проекте. Теперь вы можете создать архитектуру системы.