Многие современные приложения нужно проектировать в масштабе предприятия или даже всего интернета. Все они должны отвечать требованиям масштабируемости, доступности, безопасности, надежности и отказоустойчивости.
Здесь я расскажу о некоторых шаблонах проектирования, которые помогут вам без труда достичь упомянутых выше характеристик. Подробно разберем каждый из них и рассмотрим распространенные случаи использования. Мы также узнаем, как применять эти шаблоны в облачной среде.
Некоторые из этих моделей не так уж новы, но очень полезны в современном облачном мире интернет-масштаба.
Вот список шаблонов, которые мы рассмотрим в этой статье:
1. Автоматическое прерывание (Circuit Breaker).
2. Разделение ответственности команд и запросов (CQRS).
3. Определение источников событий.
4. Шаблон расширения (Sidecar).
5. Backend-for-Frontend.
6. Шаблон подавления (Strangler).
Итак, начнем.
Автоматическое прерывание (Circuit Breaker)
Распределенные системы необходимо проектировать с учетом отказов. Сейчас микросервисы стали распространенным явлением. Чаще всего они зависят от других удаленных сервисов, которые могут по различным причинам не реагировать вовремя, например из-за проблем с сетью, загрузки приложений и т.д. В большинстве случаев для решения подобных проблем достаточно реализации повторных попыток.
Но иногда могут возникнуть серьезные проблемы, например деградация сервиса или полный отказ сервиса как такового. В таких случаях повторять попытки бессмысленно. Вот где может пригодиться схема автоматического прерывания.
На диаграмме выше показана реализация схемы автоматического прерывания: когда сервис-1 понимает, что при вызове сервиса-2 происходят непрерывные сбои или тайм-ауты, вместо повторной попытки сервис-1 отключает вызовы сервиса-2 и возвращает резервный ответ.
Существуют популярные библиотеки с открытым исходным кодом, например Hystrix от Netflix или Reselience4J, которые можно применить для удобной реализации этого шаблона.
Если вы используете API-шлюзы или внешние прокси-серверы, такие как Envoy, то можно добиться этого и на уровне прокси.
Примечание. При разомкнутом контуре должно реализовываться достаточное количество журналов и оповещений. Так вы сможете отслеживать запросы, полученные в течение этого времени, а проектная группа будет в курсе происходящего.
Также можно реализовать автоматическое прерывание с полуоткрытым контуром, чтобы обслуживать клиентов даже при падении качества сервиса.
Когда использовать этот шаблон
- Когда сервис зависит от другого удаленного сервиса, и есть вероятность его отказа в некоторых сценариях.
- Когда сервис имеет очень высокую зависимость (например, сервисы мастер-данных).
Когда не следует использовать этот шаблон
- Когда вы имеете дело с локально-зависимыми объектами, автоматическое прерывание может привести к чрезмерному потреблению ресурсов.
Разделение ответственности команд и запросов (CQRS)
CQRS (Command Query Responsibility Segregation) — очень полезный шаблон для современных приложений, взаимодействующих с хранилищами данных. Он основан на принципе разделения операций чтения (запрос) и записи/обновления (команда) в хранилище данных.
Предположим, вы создаете приложение, которое требует хранить данные в такой базе, как MySQL/PostgreSQL и т.п. Как известно, при записи данных в хранилище операция должна выполняться в несколько шагов, например проверка, моделирование и сохранение. Следовательно типичные операции записи/обновления занимают больше времени, чем простые операции чтения.
Когда вы используете единичное хранилище данных одновременно для операций чтения и записи, к тому же в масштабе, у вас могут начаться проблемы с производительностью.
В таких случаях пригодится шаблон CQRS. Он предполагает использование различных моделей данных для операций чтения и записи. Некоторые варианты также предполагают использование отдельных хранилищ данных для этих моделей.
Примечание. В настоящее время большинство баз данных PaaS предоставляют возможность создавать реплики для чтения (Google Cloud SQL, Azure SQL DB, Amazon RDS и т.д.) для хранилищ данных, которые значительно упрощают репликацию данных.
Многие корпоративные базы данных также предоставляют эту возможность, если вы имеете дело с локальными БД.
Примечание. Сейчас также есть тенденция реализовывать реплики чтения как быстрые и производительные базы данных NoSQL, к примеру MongoDB и Elasticsearch.
Когда использовать этот шаблон
- При масштабировании приложения, когда ожидается огромное количество операций чтения и записи.
- Если вы хотите отдельно настроить производительность для операций чтения и записи.
- Когда операции чтения происходят практически в реальном времени или же последовательно.
Когда не следует использовать этот шаблон
- Когда вы создаете обычное приложение CRUD, в котором не ожидается огромного количества одновременных операций чтения и записи.
Определение источников событий
Определение источников событий — интересный шаблон проектирования, в котором последовательность событий домена хранится в виде журнала, агрегированное представление которого представляет текущее состояние приложения.
Этот шаблон обычно применяют для систем, которые не могут позволить себе блокировки хранилища данных и которым необходимо вести ревизию и сохранять историю событий. Например, для приложений по бронированию отелей, конференций, мест.
Рассмотрим систему бронирования гостиничных номеров, где пользователи осуществляют или отменяют бронирование. Здесь нужно хранить заказы и отмены как серии событий. Перед каждым бронированием сводное представление просматривает журнал событий и затем показывает доступные номера.
Примечание. Большинство поставщиков облачных услуг поддерживают службы обмена сообщениями, например Google Pub/Sub, Azure Service Bus, AWS SQS и т.д. Эти службы в сочетании с надежными хранилищами данных могут применяться для реализации этого шаблона.
Когда использовать этот шаблон
- Когда регулярные CRUD-операций недостаточно удовлетворяют требованиям.
- Как правило, он подходит для систем бронирования мест, например в автобусах, поездах, на конференциях, в кинозалах, или систем электронной коммерции, которые включают такие события, как манипуляции с корзиной, платежи и т.д.
- Когда существует потребность в постоянной ревизии и воспроизведении событий для сохранения текущего и прошлого состояния приложений.
Когда не следует использовать этот шаблон
- Когда регулярных CRUD-операций достаточно, чтобы удовлетворить потребности пользователя.
Шаблон расширения (Sidecar)
Расширение за счет внешних систем стало популярным с появлением микросервисов. В этом шаблоне некий компонент приложения развертывается в отдельном процессе или контейнере. Это помогает достичь абстрагирования и инкапсуляции.
Envoy Proxy — один из самых популярных внешних прокси-серверов, нашедший широкое применение. Он помогает разместить основные функциональные возможности приложения отдельно, воспользовавшись расширением для изоляции общих функций, таких как работа с сетью, наблюдаемость и безопасность.
Такой тип внешних устройств помогает абстрагировать коммуникации типа L4/L7. Sidecar-расширения, подобные Envoy Proxy, даже способствуют более высокой безопасности при взаимной реализации протокола TLS.
Для достижения лучшей связи и безопасности между различными микросервисами шаблон Sidecar можно применять в сочетании с сервисной сеткой.
Когда использовать этот шаблон
- Когда вы имеете дело с множеством однообразных микросервисов в области продукта.
- Когда вы имеете дело с устаревшими приложениями, которые не справляются с новыми проблемами коммуникации и безопасности.
Когда не следует использовать этот шаблон
- Когда вы имеете дело с ограниченным количеством взаимодействующих сервисов.
- В небольших приложениях, где развертывание внешних устройств неэкономично или неудобно в эксплуатации.
Backend-for-Frontend (BFF)
В типичном цикле разработки продукта бэкенд-инженеры отвечают за создание сервисов, взаимодействующих с хранилищами данных, а фронтенд-инженеры разрабатывают пользовательские интерфейсы. Современные приложения должны быть построены с учетом как мобильных устройств, так и компьютеров.
Несмотря на то, что разрыв между мобильными и стационарными устройствами с точки зрения аппаратного обеспечения становится все меньше, доступ и использование по-прежнему представляют собой сложные задачи для мобильных устройств.
В таких случаях может оказаться полезным шаблон Backend-for-Frontend. Здесь ожидается, что вы создаете/настраиваете сервисы бэкенда под конкретный внешний интерфейс.
Для оптимизации работы мобильных клиентов можно создать отдельную серверную службу, которая предоставляет легкие и разбитые на страницы ответы.
Вы также можете воспользоваться данным шаблоном для агрегации различных сервисов, чтобы уменьшить лишний обмен сообщениями.
Примечание. Если вы пользуетесь API-шлюзом, то сегодня шаблон BFF легко поддается реализации непосредственно в самом шлюзе, так что вам не придется поддерживать отдельные службы.
Когда использовать этот шаблон
- Когда вы хотите предоставлять продукт/услугу для разных клиентов (мобильных и стационарных устройств).
- Когда вы хотите оптимизировать ответ для конкретного типа клиента.
- Когда вы хотите уменьшить обмен сообщениями между мобильными клиентами и различными сервисами.
Когда не следует использовать этот шаблон
- Когда ожидается, что пользовательский интерфейс будет единым для всех.
- Когда ожидается, что мобильные и компьютерные приложения будут демонстрировать аналогичную информацию и предоставлять аналогичную функциональность.
Подавление (Strangler)
Если вы работаете в организации, которая находится в процессе модернизации приложений, то шаблон подавления, он же Strangler, именно то, что вам нужно. Шаблон проектирования Strangler предполагает создание внешнего интерфейса поверх легаси-кода и нового кода приложения, таким образом предоставляя потребителю обобщенный вид.
Эта модель отделяет пользователей от деятельности, связанной с миграцией приложения.
Примечание. Если вы переходите от одной ERP-системы к другой, то этот тип шаблона окажется чрезвычайно полезен. Если вы пользуетесь API-шлюзом, его еще проще реализовать через прокси-сервер самого шлюза.
Вам только нужно решить, хотите ли вы сохранить интерфейс после миграции или избавиться от него.
Когда использовать этот шаблон
- Когда вы переносите или модернизируете сложное, сильно зависимое приложение, например в случаях миграции ERP-систем.
Когда не следует использовать этот шаблон
- Когда переход достаточно прост, а прямая замена — наилучший вариант.
Читайте также:
- Под покровом капустного листа: шаблон Декоратор
- Сказание о шаблоне Стратегия и его реализации
- 4 лучших шаблона для написания простого кода
Читайте нас в Telegram, VK и Яндекс.Дзен
Перевод статьи Tanmay Deshpande: Modern-Day Architecture Design Patterns for Software Professionals