Привет, Хабр! Представляю вашему вниманию перевод статьи "Modern-Day Architecture Design Patterns for Software Professionals" автора Tanmay Deshpande.

image
Многие современные приложения необходимо создавать в масштабах предприятия, иногда даже в масштабах Интернета. Каждое приложение должно соответствовать требованиям к масштабируемости, доступности, безопасности, надежности и отказоустойчивости.

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

Вот список шаблонов, которые я буду обсуждать в этой статье:

  1. Circuit Breaker
  2. Command and Query Responsibility Segregation (CQRS)
  3. Event Sourcing
  4. Sidecar
  5. Backend-for-Frontend
  6. Strangler

Итак, давайте начнем.

1. Circuit Breaker (Автоматический выключатель)


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

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

image

На приведенной выше диаграмме показана реализация схемы автоматического выключателя, где, когда сервис 1 понимает, что при вызове сервиса 2 происходят непрерывные сбои/таймауты, вместо повторных попыток, сервис 1 отключает звонки в сервис 2 и возвращает ответ в случае отказа.

Существуют популярные библиотеки с открытым исходным кодом, такие как Netflix Hystrix
или Reselience4J, которые могут быть использованы для реализации этого шаблона очень легко.

Если вы используете API шлюзы или прокси–серверы
вроде Envoy, то это может быть достигнуто на самом прокси–уровне.

Примечание: Очень важно, чтобы было реализовано достаточное количество логов и предупреждений, когда цепь открыта, чтобы отслеживать запросы, полученные в течение этого времени, и чтобы операционная команда знала об этом.

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

Когда стоит использовать этот паттерн

  • Когда служба зависит от другого удаленного сервиса, и в некоторых сценариях она, скорее всего, откажет.
  • Когда служба имеет очень сильную зависимость (например, службы master data).

Когда не стоит использовать этот паттерн

  • Когда вы имеете дело с локальными зависимостями — автоматический выключатель может создать накладные расходы.

2. Command and Query Responsibility Segregation (CQRS) (Сегрегация ответственности за команды и запросы (CQRS))


CQRS является очень полезной моделью для современных приложений, которые предполагают использование хранилищ данных. Она основана на принципе разделения операций чтения (запрос) и записи/обновления (команда) в хранилище данных.

Скажем, вы строите приложение, которое требует хранения данных в базе данных, такой как MySQL/PostgreSQL и т.д. Как все знают, при записи данных в хранилище операция должна пройти несколько этапов — например, проверку, моделирование и персистентность — и, следовательно, типичные операции записи/обновления занимают больше времени, чем простые операции чтения.

Когда вы используете одно хранилище данных для одновременного выполнения операций чтения и записи и в масштабе, вы можете начать видеть проблемы с производительностью.
В таких случаях шаблон CQRS может быть полезен. Шаблон CQRS предлагает использовать различные модели данных для операций чтения и записи. Некоторые вариации также предлагают использовать отдельные хранилища данных для этих моделей.

image

Примечание: Большинство PaaS баз данных в наши дни предоставляют возможность создания читаемых реплик (Google Cloud SQL, Azure SQL DB, Amazon RDS
и т.д.) хранилищ данных, которые помогают значительно легче добиться репликации данных.
Многие базы данных предприятий также предоставляют эту возможность, если вы имеете дело с локальными базами данных.

Примечание: В наши дни некоторые люди также предпочитают реализовывать читаемые реплики в качестве быстрых и производительных баз данных NoSQL, таких как MongoDB и Elasticsearch.

Когда стоит использовать этот паттерн

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

Когда не стоит использовать этот паттерн

  • Когда вы строите обычное приложение CRUD, которое не ожидает огромного количества чтений и записей за один раз.

3. Event Sourcing (Источник событий)


Источник событий — это интересный шаблон проектирования, в котором последовательность доменных событий хранится в виде журнала, а агрегированный вид журнала дает текущее состояние приложения.

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

image

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

Примечание:Большинство провайдеров облачных услуг поддерживают такие службы обмена сообщениями, как Google Pub/Sub, Azure Service Bus, AWS SQS и т. д. Эти сервисы, в сочетании с сильными консистентными хранилищами данных, могут быть использованы для реализации этой схемы.

Когда стоит использовать этот паттерн

  • Когда обычные операции CRUD не достаточно хороши для удовлетворения требований
  • Обычно подходит для систем резервирования мест — например, для автобусов, поездов, конференций, кинозалов и т.д. — или для систем электронной коммерции, которые состоят из таких мероприятий, как операции с тележками, платежи и т.д.
  • Когда существует потребность в сильном аудите и воспроизведении событий для создания текущего и прошлого состояния приложений.

Когда не стоит использовать этот паттерн

  • Когда обычные операции CRUD достаточно хороши для удовлетворения потребностей пользователя.

4. Sidecar (Шаблон проектирования Сайдкар)


Паттерн Sidecar стал популярной с появлением микросервисов. В этой схеме компонент приложения развертывается в отдельный процесс или контейнер. Это помогает добиться абстракции и инкапсуляции.

Envoy Proxy является одним из самых популярных прокси–серверов sidecar и широко используется. Он помогает вам отделить основную функциональность приложения, используя боковую машину для изоляции общих функций, таких как работа в сети, наблюдаемость и безопасность.

image

Такой тип сайдкара может помочь абстрактному L4/L7 типу связи. Такие сайдкары, как Envoy Proxies, даже помогают достичь более высокой безопасности за счет реализации взаимного TLS.
Вы можете использовать это в комбинации с сервисной сеткой для достижения лучшей связи и безопасности между различными микросервисами. Подробнее об этом вы можете прочитать в моей предыдущей статье.

Когда стоит использовать этот паттерн

  • Когда вы имеете дело с многочисленными и гетерогенными микросервисами в ассортименте продукции.
  • Когда вы имеете дело с устаревшими приложениями, которые, как правило, не справляются с проблемами взаимодействия и безопасности новой эпохи.

Когда не стоит использовать этот паттерн

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

5. Бэкэнд–для–Фронта (BFF)


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

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

В таких сценариях, BFF шаблоны становятся довольно удобными. Здесь, вы, как ожидается, построить / настроить внутренние службы для конкретного front–end.

image

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

Примечание:В наши дни, если вы используете шлюз API, шаблон BFF может быть легко реализован в самом шлюзе, и вам не нужно будет обслуживать отдельные службы.

Когда стоит использовать этот паттерн

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

Когда не стоит использовать этот паттерн

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

6. Strangler (Паттерн Душитель)


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

image

Этот паттерн отделяет клиентов от миграционной активности между старыми и новыми частями приложения.

Примечание: В типичной ИТ–организации, если вы осуществляете миграцию с одной ERP–системы на другую, этот тип схемы будеи чрезвычайно полезен. Если вы используете API шлюз, то реализовать это в самом прокси-шлюзе будет проще.

Вам нужно решить, хотите ли вы сохранить надстройку (фасад) в конце миграции или удалить его.

Когда стоит использовать этот паттерн

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

Когда не стоит использовать этот паттерн
  • Когда миграция проста и прямая замена — лучший вариант.