8 шаблонов проектирования микросервисов для опытных разработчиков
В то время как отраслевая тенденция заключается в разделении вашего монолитного приложения на микросервисы для разделения данных, кода и интерфейса, это непростая задача, особенно если у вас нет никакого опыта в разработке микросервисов и вы не знакомы с лучшими практиками и основными шаблонами и принципами проектирования микросервисов.
Как и шаблоны объектно-ориентированного проектирования, шаблоны микросервисов также являются испытанным решением распространённых проблем, с которыми люди сталкиваются при разработке, развёртывании и масштабировании своих микросервисов.
Например, шаблон SAGA решает проблему сбоев распределённых транзакций, а API gateway упрощает код на стороне клиента, а также выступает в качестве внешнего контроллера и балансировщика нагрузки для многих ваших микросервисов и, таким образом, делает их более удобными в обслуживании.
В этой статье я собираюсь дать вам краткий обзор основных шаблонов микросервисов и того, когда их следует использовать, с простыми примерами и сценариями.
Это минимум, который вам нужно знать и помнить как разработчику микросервисов, если вы знаете основы и имеете хоть какую-то идею, вы всегда можете вернуться к поиску и изучить их подробно, прежде чем фактически использовать в своём проекте.
Вот несколько популярных шаблонов проектирования микросервисов, которые должен знать программист:
- Service Registry
- Circuit Breaker
- API Gateway
- Saga Pattern
- Event Sourcing Pattern
- Command Query Responsibility Segregation (CQRS)
- Bulkhead Pattern
- Backends for Frontends (BFF)
8 основных шаблонов проектирования микросервисов для опытных разработчиков
Вот список популярных шаблонов проектирования микросервисов, которые должен знать каждый разработчик, если он работает в микросервисах или разбивает своё монолитное приложение на микросервисы для разделения кода, данных и интерфейсов:
1. Service Registry Pattern
Service Registry Pattern предоставляет центральное хранилище для поиска микросервисов по имени. Это шаблон архитектуры микросервиса, который позволяет службам обнаруживать другие микросервисы и взаимодействовать друг с другом.
В этом шаблоне центральный реестр служб или каталог используется для ведения записей о доступных службах и их местоположениях. Микросервисы могут регистрировать себя в реестре, а другие микросервисы могут просматривать реестр, чтобы найти местоположение требуемых служб.
Например, предположим, что у нас есть большой веб-сайт электронной коммерции, который состоит из множества микросервисов, таких как служба заказов, платёжная служба, служба доставки и служба поддержки клиентов. Каждая из этих служб имеет свой собственный REST API, который другие службы могут использовать для взаимодействия с ней.
Чтобы этим службам было проще обнаруживать друг друга, мы можем использовать Service Registry Pattern. Мы можем настроить реестр служб, таких как Consul или Eureka (Spring cloud предоставляет это), который поддерживает список всех доступных служб и их конечных точек.
Когда служба запускается, она может зарегистрировать себя в реестре, указав своё имя и конечную точку.
Например, служба заказов может зарегистрировать себя как “служба заказов” с конечной точкой “http://order-service:8080 “. Другие службы, которым необходимо взаимодействовать со службой заказа, могут затем найти её конечную точку в реестре, используя её имя.
Например, платёжная служба может искать конечную точку “служба заказов” в реестре, чтобы отправить платёжную информацию в службу заказов. Аналогично, служба доставки может искать конечную точку “заказ-сервис” в реестре, чтобы получить информацию о доставке для заказа.
Таким образом, каждая служба может быть разработана и развёрнута независимо, без кодирования конечных точек других служб в её коде. Service Registry Pattern позволяет службам динамически находить друг друга, делая систему более гибкой и устойчивой к изменениям.
2. Circuit Breaker Pattern
Как следует из названия, Circuit Breaker Pattern предотвращает каскадный сбой путём разрыва цепи и позволяет приложениям продолжать функционировать при сбое одной или нескольких служб. Он используется для обработки ошибок, которые могут возникать в микросервисной архитектуре.
В этом случае Circuit Breaker Pattern действует как защитная сетка между клиентом и сервисом, защищая клиента от сбоев в работе сервиса. Circuit Breaker Pattern отслеживает состояние службы и, если он обнаруживает, что служба выходит из строя, он может разомкнуть цепь и предотвратить отправку дальнейших запросов в службу до тех пор, пока служба не восстановится.
Например, предположим, что микросервисное приложение использует внешнюю службу, которая ненадёжна, и приложению необходимо продолжать функционировать, даже если внешняя служба выходит из строя.
В этом сценарии шаблон Circuit Breaker Pattern может использоваться для определения того, когда внешняя служба недоступна, и переключения на альтернативную службу или резервную службу до тех пор, пока внешняя служба снова не станет доступной.
В микросервисной архитектуре шаблон Circuit Breaker Pattern может быть реализован с помощью таких инструментов, как Hystrix от Netflix или Spring Cloud Circuit Breaker, которые обеспечивают способ управления поведением Circuit Breaker Pattern и позволяют приложению реагировать на сбои в обслуживании контролируемым образом.
3. API Gateway Pattern
API Gateway Pattern – это ещё один распространённый шаблон проектирования, используемый в архитектуре микросервисов, который включает API gateway, который действует как точка входа для всех входящих запросов API. Он обеспечивает единую точку входа для всех микросервисов и действует как прокси-сервер между клиентами и микросервисами, направляя запросы в соответствующую службу.
Основная цель API Gateway Pattern – отделить клиентов от микросервисов, абстрагируя сложность системы за упрощённым и согласованным API. Это также означает, что вам не нужно находить и запоминать адреса более чем 100 микросервисных REST API.
Этот микросервис обеспечивает дополнительный уровень безопасности и управления, позволяя организациям контролировать доступ к своим службам и управлять ими, отслеживать производительность системы и применять политики во всех службах.
Вот пример того, как API Gateway Pattern работает в простой системе электронной коммерции:
Предположим, система электронной коммерции имеет несколько микросервисов для обработки различных функций, таких как управление заказами, каталог товаров и аутентификация пользователя. Каждый микросервис имеет свою собственную конечную точку API для обработки запросов. Однако клиенту, которым может быть веб-приложение или мобильное приложение, необходимо получить доступ ко всем этим микросервисам через единую точку входа.
Вот тут-то и вступает в игру API Gateway Pattern. Он действует как обратный прокси-сервер, который получает все входящие запросы от клиентов. Затем он направляет каждый запрос в соответствующий микросервис на основе запрошенной конечной точки.
Например, API Gateway Pattern может направлять запросы к конечной точке /orders в микросервис управления заказами, а запросы к конечной точке /products – в микросервис каталога продуктов.
API Gateway Pattern также может выполнять дополнительные функции, такие как преобразование запросов и ответов, ограничение скорости, аутентификация и авторизация, а также кэширование.
Он также может предоставить унифицированный API, который скрывает внутренние детали микросервисов и представляет клиентам более простой и согласованный интерфейс.
В целом, API Gateway Pattern обеспечивает масштабируемый, гибкий и безопасный способ управления микросервисами в сложной системе, упрощая разработку, развёртывание и обслуживание приложений на основе микросервисов.
4. Saga Pattern
Saga Pattern предоставляет способ управления транзакциями, в которых задействовано несколько микросервисов. Он используется для обеспечения успешного завершения серии транзакций в нескольких службах, а если нет, то для отката или отмены всех изменений, которые были внесены до этого момента.
Saga Pattern состоит из последовательности локальных транзакций, каждая из которых обновляет состояние отдельной службы, и соответствующего набора компенсирующих транзакций, которые используются для отмены последствий исходных транзакций в случае сбоя.
Вот пример того, как Saga Pattern используется в приложении электронной коммерции на основе микросервиса:
Предположим, у вас есть два микросервиса, один из которых отвечает за обработку заказов, а другой – за доставку заказов.
При размещении нового заказа служба обработки заказов отвечает за подтверждение заказа и обеспечение наличия товаров на складе, в то время как служба доставки отвечает за упаковку заказа и отправку его клиенту.
Если служба обработки заказов определяет, что заказ действителен и все товары есть на складе, она отправляет сообщение службе доставки, чтобы инициировать процесс доставки. На этом этапе в игру вступает Saga Pattern.
Служба доставки создаст новую транзакцию для упаковки и отправки заказа, и если транзакция пройдёт успешно, она пометит заказ как отправленный.
Если, с другой стороны, транзакция завершится неудачей (возможно, из-за проблемы с поставщиком доставки), служба доставки инициирует компенсирующую транзакцию, чтобы отменить последствия первоначальной транзакции, такие как отмена отправки и пополнение запасов товаров.
Между тем, служба обработки заказов также использует Saga Pattern для управления своей собственной транзакцией. Если служба доставки сообщает, что заказ был успешно отправлен, служба обработки заказов отметит заказ как выполненный.
Если служба доставки сообщит о сбое, служба обработки заказа инициирует компенсирующую транзакцию, чтобы отменить заказ и вернуть все уплаченные средства.
В целом, Saga Pattern предоставляет способ управления сложными транзакциями между несколькими микросервисами таким образом, чтобы обеспечить согласованность и надёжность. Если вам нужно выучить только один инструмент, вам лучше изучить Saga Patterns, поскольку они чрезвычайно полезны в микросервисных приложениях.
5. Event Sourcing Pattern
Event Sourcing Pattern – это шаблон микросервиса, используемый для сохранения и запроса данных в приложении. Вместо сохранения текущего состояния объекта, Event Sourcing сохраняет все события, которые происходят в приложении, позволяя восстанавливать состояние объекта в любой момент времени.
В этом шаблоне каждое изменение состояния в приложении фиксируется как событие и сохраняется в виде журнала событий. Состояние приложения может быть восстановлено путём воспроизведения этих событий. Это означает, что источник событий предоставляет журнал всех изменений, которые происходят в приложении.
Например, рассмотрим приложение для электронной коммерции. Когда пользователь размещает заказ, генерируется событие OrderPlaced, которое сохраняется в журнале. Когда заказ отправлен, генерируется событие ShipmentMade, которое сохраняется в журнале.
Если заказ отменён, генерируется событие OrderCanceled, которое сохраняется в журнале. Путём воспроизведения событий можно определить текущее состояние заказа.
Event Sourcing Pattern имеет несколько преимуществ:
- Проверяемость: Все изменения в системе могут быть проверены.
- Масштабируемость: События могут обрабатываться параллельно, что обеспечивает лучшую масштабируемость.
- Гибкость: Поскольку события являются источником истины, можно изменить способ запроса и сохранения данных без изменения самих данных.
- Отказоустойчивость: Поскольку события неизменяемы, они не могут быть изменены, гарантируя, что данные всегда верны.
Однако внедрение Event Sourcing Pattern может быть сложным и требует тщательного планирования. Кроме того, запрос данных может быть медленнее, поскольку он включает в себя воспроизведение всех событий, поэтому вы должны убедиться, что они вам действительно нужны, прежде чем использовать их.
6. Command Query Responsibility Segregation (CQRS) Pattern:
Command Query Responsibility Segregation (CQRS) Pattern) – это ещё один популярный шаблон проектирования микросервисов, который разделяет команды (операции записи) и запросы (операции чтения) на отдельные модели, каждая со своей собственной базой данных.
Шаблон основан на идее, что модели, используемые для записи данных, не совпадают с моделями, используемыми для чтения данных.
В этом шаблоне командная модель получает команды от клиента и записывает их в базу данных. Модель запроса считывает данные из базы данных и отправляет их клиенту. Шаблон может быть использован для повышения производительности и масштабируемости системы, поскольку каждая модель может быть оптимизирована для своей конкретной задачи.
Например, рассмотрим приложение для электронной коммерции, которое использует традиционный подход к управлению информацией о продукте на основе CRUD. Одна и та же модель и база данных используются как для чтения, так и для записи информации о продукте. По мере роста приложения модель становится всё более сложной, а база данных начинает снижать производительность этого приложения.
Используя CQRS, приложение будет иметь отдельную модель команд для записи информации о продукте и отдельную модель запросов для чтения информации о продукте. Модель команд была бы оптимизирована для быстрой записи, в то время как модель запросов была бы оптимизирована для быстрого чтения.
Command Model будет хранить данные в базе данных, оптимизированной для записи, в то время как модель запросов будет хранить данные в базе данных, оптимизированной для чтения. Две модели будут взаимодействовать через шину событий или очередь сообщений.
В целом, CQRS может улучшить масштабируемость и производительность системы, а также упростить кодовую базу за счёт разделения функционала. Однако, это также может усложнить и потребовать дополнительных усилий по разработке, поскольку требуются отдельные модели и базы данных.
7. Bulkhead Pattern
Bulkhead Pattern – это способ изоляции различных частей системы таким образом, чтобы сбой в одной части не повлиял на остальную систему. В микросервисной архитектуре Bulkhead Pattern может использоваться для изоляции различных микросервисов, чтобы сбой в одном микросервисе не приводил к выходу из строя всей системы.
Это выглядит очень похоже на Circuit Breaker Pattern, который также предотвращает каскадный сбой, но вместо разрыва цепи этот шаблон проектирования фокусируется на изоляции и самодостаточных микросервисах, как показано на диаграмме ниже. Служба A имеет свой собственный пул подключений, который не используется совместно между службами B и C.
8. Backends for Frontends (BFF)
Backends for Frontends (BFF) – это шаблон проектирования, используемый в микросервисной архитектуре для обработки сложности взаимодействия клиент-сервер в контексте множества пользовательских интерфейсов. Он предполагает наличие отдельной серверной службы для каждого интерфейса для удовлетворения конкретных потребностей этого интерфейса.
Это позволяет разработчикам оптимизировать потоки данных, механизмы кэширования и аутентификации для уникальных потребностей интерфейсной части, сохраняя при этом модульность и несвязанность внутренних служб.
Например, предположим, что у вас есть веб-приложение и мобильное приложение, которым необходим доступ к одному и тому же набору служб. В этом случае вы можете создать отдельные серверные службы для каждого приложения, каждая из которых оптимизирована для конкретной платформы.
Серверная часть веб-приложения может обрабатывать большие объёмы данных для более быстрой загрузки, в то время как серверная часть мобильного приложения может оптимизировать для снижения задержек и использования сети.
Этот шаблон позволяет командам оптимизировать пользовательский интерфейс для каждого интерфейса, используя отдельные внутренние службы для каждого из них. Это также позволяет им избежать наличия единой серверной службы, которая должна обслуживать множество различных интерфейсов с разными потребностями, что может становиться всё более сложным и труднодоступным в обслуживании.
Заключение
Если вы захотите узнать больше о микросервисах, есть хорошая книга Криса Ричардсона “Microservices Patterns”, которую определённо стоит прочитать Java-разработчикам.
У каждого шаблона, перечисленного в этой статье, есть свои преимущества и недостатки, и выбор шаблона будет зависеть от конкретных потребностей приложения. Но если вы не знаете, что они делают и какую проблему решают, вы не сможете использовать их.
Кстати, это лишь некоторые из множества доступных шаблонов проектирования микросервисов, которые вы можете изучить самостоятельно. В будущем я также постараюсь поделиться и другими шаблонами.