В 2018 году экспертом, консультантом и архитектором Chris Richardson были опубликованы паттерны микросервисной архитектуры в одноименной книге
Microservices Patterns и на
сайте. На текущий момент описан 51 паттерн, которые разделены на 3 уровня (Application, Application Infrastructure, Infrastructure) и 15 категорий: Architectural style, Service boundaries, Refactoring to services, Service collaboration, Transactional messaging, Testing, Deployment, Cross-cutting concerns, Communication styles, External API, Service discovery, Reliability, Security, Observability, UI design.
Представленный набор паттернов помогает решать проблемы, связанные с архитектурой, разработкой и эксплуатацией, и позволяет разработчикам эффективно применять микросервисную архитектуру. Под паттерном понимается повторно используемое решение проблемы, возникающей в определенном контексте, а также описание последствий этого решения. Для структурирования паттернов использовался следующий формат:
- Контекст (Context) — ситуация, в рамках которой применим данный паттерн;
- Проблема (Problem) — проблема, которую решает паттерн;
- Силы (Forces) — факторы, ограничения и соображения, которые необходимо учитывать и которые могут влиять на применимость решения;
- Решение (Solution) — предлагаемое паттерном решение;
- Последствия (Consequences) — описание последствий применения паттерна: положительные результаты, отрицательные результаты и проблемы, возникающие в результате применения паттерна;
- Связанные паттерны (Related patterns) — паттерны, предназначенные для решения проблем, порождаемых данным паттерном, а также альтернативные способы решения той же проблемы.
Полный список из 51 паттерна микросервисной архитектуры с описанием и разделенных на 15 категорий:
Архитектурный стиль (Architectural style). Какой архитектурный стиль следует выбрать для приложения?
- Monolithic architecture — проектирование приложения как единого развертываемого компонента;
- Microservice architecture — проектирование приложения как набора независимо развертываемых, слабо связанных сервисов.
Границы сервисов (Service boundaries). Как декомпозировать приложение на сервисы?
- Decompose by business capability — определение сервисов, соответствующих бизнес возможностям;
- Decompose by subdomain — определение сервисов, соответствующих поддоменам DDD (Domain-Driven Design);
- Self-contained Service — проектирование сервисов таким образом, чтобы они обрабатывали синхронные запросы без ожидания ответов от других сервисов;
- Service per team — каждый сервис принадлежит одной команде, которая несет полную ответственность за внесение изменений.
Рефакторинг в сторону сервисов (Refactoring to services). Как выполнить поэтапный переход от существующего приложения к сервисам?
- Strangler Application — модернизация приложения за счет поэтапной разработки нового (strangler) приложения вокруг легаси приложения;
- Anti-corruption layer — определение слоя, выполняющего преобразование между двумя доменными моделями.
Взаимодействие сервисов (Service collaboration). Как реализовать сценарии, охватывающие несколько сервисов?
- Database per Service — у каждого сервиса есть собственная приватная база данных;
- Shared database — сервисы используют общую базу данных;
- Saga — использование саг (sagas), представляющих собой последовательности локальных транзакций, для поддержания согласованности данных между сервисами;
- Command-side replica — поддержание доступной для запросов реплики данных в сервисе, который реализует команду;
- API Composition — реализация запросов путем вызова сервисов, владеющих данными, и выполнения объединения данных в памяти;
- CQRS (Command Query Responsibility Segregation) — реализация запросов за счет поддержки одного или нескольких материализованных представлений, доступных для эффективного выполнения запросов;
- Domain event — публикация события при каждом изменении данных;
- Event sourcing — сохранение агрегатов в виде последовательности событий.
Транзакционный обмен сообщениями (Transactional messaging). Как отправлять сообщения в рамках транзакции базы данных?
- Transactional outbox — сервис, отправляющий сообщения, сначала сохраняет сообщение в базе данных как часть транзакции, которая обновляет бизнес-сущности;
- Transaction log tailing — чтение журнала транзакций базы данных и публикация каждого сообщения или события, добавленного в outbox, в брокер сообщений;
- Polling publisher — публикация сообщений путем опроса таблицы outbox в базе данных.
Тестирование (Testing). Как тестировать сервисы?
- Consumer-driven contract test — набор тестов для сервиса, который разрабатывается разработчиками другого сервиса, использующего этот сервис;
- Consumer-side contract test — набор тестов для клиента сервиса (например, другого сервиса), который проверяет возможность корректного взаимодействия с сервисом;
- Service component test — набор тестов, проверяющий сервис изолированно с использованием тестовых двойников (test doubles) для всех сервисов, которые он вызывает.
Развертывание (Deployment). Как развертывать сервисы приложения?
- Multiple service instances per host — развертывание нескольких экземпляров сервиса на одном хосте;
- Service instance per host — развертывание каждого экземпляра сервиса на отдельном хосте;
- Service instance per VM — развертывание каждого экземпляра сервиса в отдельной виртуальной машине;
- Service instance per Container — развертывание каждого экземпляра сервиса в отдельном контейнере;
- Serverless deployment — развертывание сервиса с использованием serverless-платформы;
- Service deployment platform — развертывание сервисов с использованием высокоавтоматизированной платформы развертывания, предоставляющей абстракцию сервиса.
Сквозные аспекты (Cross-cutting concerns). Как работать со сквозными аспектами?
- Microservice chassis — фреймворк, который обрабатывает сквозные аспекты и упрощает разработку сервисов;
- Externalized configuration — вынесение всей конфигурации, такой как расположение базы данных и учетные данные;
- Service Template — шаблон, реализующий стандартные сквозные аспекты и предназначенный для копирования разработчиком с целью быстрого начала разработки нового сервиса.
Стили коммуникации (Communication styles). Какие механизмы сервисы используют для коммуникации друг с другом и с внешними клиентами?
- Remote Procedure Invocation — использование протокола на основе RPI для межсервисной коммуникации;
- Messaging — использование асинхронного обмена сообщениями для межсервисной коммуникации;
- Domain-specific protocol — использование предметно-ориентированного протокола;
- Idempotent Consumer — обеспечение способности потребителей сообщений корректно обрабатывать многократные вызовы с одним и тем же сообщением.
Внешний API (External API). Как внешние клиенты взаимодействуют с сервисами?
- API gateway — сервис, предоставляющий каждому клиенту унифицированный интерфейс для доступа к сервисам;
- Backend for front-end — отдельный API gateway для каждого типа клиента.
Обнаружение сервисов (Service discovery). Как клиент сервиса на основе RPI определяет сетевое расположение экземпляра сервиса?
- Client-side discovery — клиент обращается к реестру сервисов для определения расположения экземпляров сервисов;
- Server-side discovery — маршрутизатор обращается к реестру сервисов для определения расположения экземпляров сервисов;
- Service registry — база данных, содержащая сведения о расположении экземпляров сервисов;
- Self registration — экземпляр сервиса самостоятельно регистрируется в реестре сервисов;
- 3rd party registration — сторонний компонент регистрирует экземпляр сервиса в реестре сервисов.
Надежность (Reliability). Как предотвратить каскадное распространение сетевых или сервисных отказов на другие сервисы?
- Circuit Breaker — вызов удаленного сервиса через прокси, который немедленно прекращает вызовы при превышении порогового уровня отказов удаленных вызовов.
Безопасность (Security). Как передавать идентичность инициатора запроса сервисам, которые обрабатывают этот запрос?
- Access Token — токен, который безопасно хранит информацию о пользователе и передается между сервисами.
Наблюдаемость (Observability). Как понять поведение приложения и устранять проблемы?
- Log aggregation — агрегация логов приложения;
- Application metrics — инструментирование кода сервиса для сбора статистики по операциям;
- Audit logging — запись действий пользователей в базу данных;
- Distributed tracing — назначение внешним запросам уникальных идентификаторов, передаваемых между сервисами, и сбор информации об их обработке в централизованном сервисе;
- Exception tracking — отправка всех исключений в централизованный сервис, который агрегирует и отслеживает исключения и уведомляет разработчиков;
- Health check API — API сервиса, который возвращает состояние работоспособности сервиса и предназначен, например, для опроса системой мониторингаж;
- Log deployments and changes — логирование каждого развертывания и каждого изменения в (production) окружении/
Проектирование UI (UI design). Как реализовать экран или страницу пользовательского интерфейса, отображающую данные из нескольких сервисов?
- Server-side page fragment composition — формирование веб-страницы на сервере путем композиции HTML фрагментов, сгенерированных несколькими веб-приложениями, привязанными к отдельным бизнес-возможностям или поддоменам;
- Client-side UI composition — формирование пользовательского интерфейса на клиенте путем композиции UI фрагментов, отрисованных несколькими UI компонентами, привязанными к отдельным бизнес-возможностям или поддоменам.
Модель паттернов микросервисной архитектуры представлена на схеме: