Микросервисная архитектура – одна из самых полезных архитектур в индустрии программного обеспечения. При правильном подходе она может помочь в создании лучших программных приложений. Из этой статьи вы узнаете, что такое микросервисная архитектура, какие шаблоны проектирования необходимы для ее реализации, а также почему стоит и почему не стоит использовать эту архитектуру для вашего нового программного обеспечения.
Микросервисы
Архитектурный паттерн, способ или стиль архитектуры, если следовать ему правильно, приведет к созданию программного приложения, состоящего из нескольких сервисов, вместо одного большого монолита.
Сервисы в этом паттерне легко разрабатывать, тестировать, деплоить и поддерживать по отдельности. Достаточно небольших команд, которые отвечают за каждый сервис, что сокращает объем коммуникаций, а также облегчает управление.
Это позволяет командам внедрять различные технологические стеки, модернизировать технологии в существующих сервисах, масштабировать, а также изменять или деплоить каждый сервис независимо.
Микросервисы против Монолитов
И микросервисы, и монолитные сервисы – это архитектурные паттерны, которые используются при разработке программных приложений для обслуживания бизнес-требований. У каждого из них есть свои преимущества, недостатки и проблемы.
С одной стороны, когда монолитные архитектуры служат в качестве крупномасштабной системы, это может усложнить ситуацию. Они могут быть громоздкими в работе, когда нужно добавить новые функции, внести изменения или даже удалить некоторые ненужные функции.
Однако монолитные архитектуры по-прежнему являются хорошим вариантом для приведенных ниже случаев:
малогабаритные приложения;
нет необходимости в обновлении технологии;
вам требуется меньше времени для вывода на рынок;
команды знакомы с Монолитными подходами.
С другой стороны, архитектура микросервисов не очень хорошо подходит для небольших приложений, требующих единого технологического стека, платформы деплоя, доменной зоны и т. д. Но для крупномасштабных приложений пока нет ничего лучше этой архитектуры.
Микросервисная архитектура является хорошим вариантом для следующих случаев:
широкомасштабные приложения;
вам необходимо обновление технологии;
разные команды работают с разными техническими скилами (языки программирования, фреймворки и другое);
если у вас есть различные домены, которые необходимо обработать;
И многие другие.
Сравнение
Сравним некоторые характеристики микросервисов и монолитной архитектуры, чтобы лучше понять их.
Характеристика | Микросервисы | Монолит |
Скорость | Сравнительно медленнее в понятиях разработки, поскольку мелкие сервисы разрабатываются отдельно. | Быстрее, когда речь идет о разработке одного приложения, содержащего почти все необходимое с самого начала. |
Независимость | Каждый сервис имеет собственное хранилище данных и отвечает за конкретный домен, и может разрабатываться, изменяться или деплоиться независимо. | Благодаря тесному взаимодействию все приложение деплоится при любом изменении, поскольку вся бизнес-логика находится в одном месте. |
Гибкость | Сервисы имеют меньший размер, что делает их легко адаптируемыми к новым технологическим изменениям. | Используется одна и та же технология, которую нельзя изменить, поскольку все приложение было разработано с ее использованием. |
Масштабирование | Легко масштабировать сервисы без ущерба для других. | Приходится масштабировать все приложение, даже если нужно масштабировать только одну фичу внутри. |
Надежность | Нет необходимости останавливать приложение, если требуется внести изменения в сервис. | Приходится заново деплоить все приложение, если что-то требует изменений. |
Тестируемость | Сервисы, специфичные для конкретного домена, легко тестировать. | Сложно протестировать всю систему сразу. |
Удобство обслуживания | Отдельные сервисы могут быть обновлены и изменены в соответствии с рыночными условиями. | Трудно поддерживать при увеличении размера приложения, поскольку изменения в одном месте могут иметь регрессивные последствия для других. |
Команды | Можно задействовать несколько небольших команд с различными наборами технологических скиллов. | Требуется одна большая команда с почти одинаковыми навыками и пониманием технологий. |
Управление | Управление различными небольшими командами, каждая из которых работает над определенной областью бизнеса, позволяет легко анализировать, кто за что отвечает. | Управление одной большой командой, работающей над полным доменом, требует внутреннего разделения. |
Коммуникация | Коммуникация медленнее, но легче. | Есть сложность общения с руководством по поводу возникающих проблем. |
Инфраструктура | Экспоненциальная стоимость, поскольку разные команды с разными навыками работают с несколькими репозиториями, средами и пайплайнами. | Экономическая эффективность, поскольку команды работают над одним и тем же репозиторием, и все команды обладают практически одинаковыми навыками в области технологий. Таким образом, нет необходимости в нескольких различных средах разработки и деплоя. |
Важные паттерны проектирования
В микросервисной архитектуре существует несколько паттернов, рассмотрим ниже некоторые из них.
Strangler
Этот паттерн предназначен для постепенного перехода к микросервисной архитектуре от монолитного приложения. Старая функциональность заменяется новыми сервисами, и последние используются после завершения работы, в то время как первые вытесняются.
Фасадный интерфейс играет важную роль в процессе, когда сервисы, отделившись от монолита, выходят во внешний мир. Таким образом, клиенты узнают о новых сервисах за фасадом, и это заслоняет старую систему.
API-шлюз
Это обеспечивает единую точку входа для всех сервисов, вместо того чтобы клиент напрямую общался с каждым сервисом. API-шлюз обеспечивает агрегацию, аутентификацию, кэширование и т.д.
API-шлюз помогает достичь следующих факторов.
Безопасность
API-шлюз не предоставляет сервисы внешнему миру напрямую, чтобы обеспечить их безопасность. Все вопросы, связанные с безопасностью, решаются на шлюзе, и только аутентифицированные клиенты получают дальнейший доступ.
Сквозные проблемы
Такие вопросы, как аутентификация, завершение SSL, ограничение скорости, дросселирование запросов, кэширование и другие, которые должны быть реализованы в каждом сервисе, находятся в ведении шлюза.
Сцепление
Клиенты взаимодействуют с сервисами через API-шлюз, что делает их более свободно связанными.
Агрегатор
Некоторые запросы требуют обращения к нескольким сервисам, что увеличивает время общения клиента с сервисами. Агрегатор может общаться со всеми сервисами и возвращать ответ после агрегации, чтобы сократить обширное общение клиента с сервисами.
Паттерн Saga
Этот паттерн помогает в управлении транзакциями, где локальные транзакции в каждом сервисе (saga) выполняются, и выдают событие для следующего сервиса, чтобы начать транзакцию. Если какая-либо из транзакций терпит неудачу, серия транзакций, компенсирующих предыдущую транзакцию, будет выполнена saga, чтобы отменить все изменения, сделанные локальными транзакциями, предшествующими этой.
Ниже приведены два способа реализации паттерна Sagа.
Хореография
В хореографии точка управления не централизована, что означает, что каждый сервис будет публиковать сообщение или событие для других сервисов, запуская локальную транзакцию.
Оркестрирование
Оркестрирование обеспечивает способ управления участниками saga (сервисами), сообщая каждому сервису о локальной транзакции, которую ему необходимо выполнить. На событийной основе операции для saga и транзакций обрабатываются оркестратором saga. Состояние отдельной задачи управляется saga, и в случае сбоя он выполнит транзакцию, чтобы компенсировать предыдущие транзакции.
Асинхронный обмен сообщениями
Некоторые запросы требуют больших вычислений и длительного времени, что может превысить лимит тайм-аута. Для таких запросов должен быть предусмотрен асинхронный механизм с использованием служб брокера сообщений, таких как Azure Service Bus Queue. Это помогает в обработке большого сообщения и в ответе на запрошенный сервис после завершения.
Circuit Breaker паттерн
Некоторые сбои могут быть временными, а некоторые - нет. Последние не должны исчерпывать ресурсы. Вместо этого необходимо прервать поток запросов и немедленно вернуть исключение обратно. Этот паттерн помогает в ситуации, когда паттерн Retry может привести к пустой трате времени и ресурсов, поскольку повторная попытка вовсе не требуется. Таймер используется для проверки того, достаточно ли восстановилась система, которая дала сбой, для использования или нет.
Этот паттерн отличается от паттерна retry, поскольку здесь смысл не в том, чтобы надеяться на успешный результат при повторной попытке, а в том, чтобы сэкономить ресурсы от ненужного использования. Паттерн circuit breaker позволяет избежать операций, которые, скорее всего, не будут выполнены.
Это действует как прокси для любой операции, которая имеет шанс потерпеть неудачу. Количество отказов отслеживается и используется для принятия решения, если оно превышает заданный порог. Существует три следующих состояния, которые похожи на автоматический выключатель в электронике.
Closed
Операция, которая должна быть выполнена, вызывается запросом. Счетчик отказов ведется прокси и увеличивается в случае неудачной операции. Если количество отказов превышает пороговое значение в течение определенного времени, то прокси переходит в состояние Open. Здесь также запускается таймер, и по истечении времени состояние прокси изменится на Half-Open.
Open
Исключение возвращается приложению сразу после получения запроса.
Half-Open
Некоторые запросы, ограниченные в количестве, разрешено передавать для вызова операции. При успешном ответе от операции состояние прокси изменится на Сlosed. Если сбой произойдет снова, то прокси перейдет в состояние Open и перезапустит таймер.
Преимущества
Меньшие размеры команды с различными наборами навыков позволяют использовать лучшее из каждого языка и фреймворка.
Более быстрый и независимый деплой, когда в действие вступает реальное использование непрерывной интеграции и деплоя.
Тестирование каждой службы является простым и менее трудоемким, поскольку службы специфичны для своего хранилища данных.
Различные технологии могут способствовать созданию комплексного решения. Переход от одной технологии к другой также прост.
Изменение в сервисе не повлияет на всю систему, что обеспечивает высокую надежность.
Недостатки
Инфраструктура требует больших затрат, поскольку различные технологии имеют различные методологии тестирования, среды для каждого сервиса и деплоя.
Дебаг может стать громоздким из-за различных логов каждого сервиса и выявления ошибок в реальном сервисе.
Полиглот микросервисов имеет и побочные эффекты, когда компании необходимо поддерживать ресурсы для каждой технологии, используемой для разработки сервисов.
В статье рассказано про микросервисную архитектуру, а также приведено сравнение ее с монолитной архитектурой. Здесь кратко обозначены их характеристики для дальнейшего понимания. Были рассмотрены важные паттерны проектирования, а также преимущества и недостатки каждой архитектуры.