Микросервисы. Стоит ли покидать монолитное царство?

Логотип компании
Микросервисы. Стоит ли покидать монолитное царство?

Изображение: Asha Sreenivas/Shutterstock.com

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

Плюсы и минусы монолитных приложений

Монолитный подход традиционно используется для развертывания приложений, при котором весь софт поставляется одним, зачастую объемным, пакетом бинарных файлов. Такие приложения включают в себя все необходимые функции и не требуют подключения к сторонним сервисам. К примеру, это могут быть разнообразные настольные приложения, такие как графический редактор Adobe Photoshop, офлайн игры вроде Fallout, а также "коробочные" версии программ, например, Microsoft Excel, или базы данных, такие как Oracle, Microsoft Server и PostgreSQL. Этот же подход применяется и при развертывании серверных приложений. Например, стартап FoodFox изначально был создан как единый монолитный сайт на PHP, и только через 5 лет был переведен на архитектуру микросервисов командой Яндекса. Сегодня сервис доступен под брендом Яндекс Еда. Сайт Auto.ru создан в 1996 году как монолитное PHP приложение. В 2014 году Яндекс приобрел сайт у его основателя и программиста Михаила Рогальского за сумму, оцениваемую в 175 миллионов долларов.

Основное преимущество разработки монолитного приложения заключается в том, что код программы обычно сосредоточен в одном месте, и для вызова функций используются внутренние библиотеки. Эти вызовы нативно поддерживаются операционными системами и широко используемыми фреймворками, включая Java, .NET, PHP, Go и Node.JS. Разработчику не требуется дополнительных усилий для развертывания и координации множества компонентов приложения или межсетевых взаимодействий. Этот подход особенно популярен среди стартапов при создании новых приложений.

Когда размер команды разработчиков увеличивается, происходит замедление развития продукта. Во-первых, возникают чаще конфликты при изменении одних и тех же участков кода. Во-вторых, даже для минимальных изменений разработчикам приходится взаимодействовать с большим количеством коллег. В-третьих, общая скорость работы команды снижается до уровня наиболее загруженного или медленного сотрудника, что хорошо иллюстрируется в книге “Проект Феникс. Как DevOps устраняет хаос и ускоряет развитие компании” авторства Кима, Бера и Спаффорда. В-четвертых, тестирование больших приложений потребляет значительные ресурсы, как в ручном, так и в автоматическом режимах. Один из разработчиков базы данных Oracle в 2018 году описывал свою работу следующим образом: 25 миллионов строк кода на C, исправление ошибки, сотни серверов, занятых компиляцией одного приложения, затем ожидание результатов автотестов от 20 до 30 часов. На следующий день обнаруживается ошибка в автотестах, и процесс начинается сначала.

Архитектура программного обеспечения наследует структуру и принципы компании

Для решения упомянутых выше проблем Amazon и Google применяют подход формирования малых команд, для которой будет достаточно двух пицц. Такие команды эффективно определяют свою сферу ответственности внутри приложения и снижают зависимость от других групп. В крупных организациях это могут быть отдельные сервисы, такие как системы аутентификации, поисковые механизмы, модули рекомендаций или рекламные блоки. В последствии размер сервисов уменьшают до микро и тогда два человека могут буть ответствеными за десятки сервисов. Приложения разделяются на мельчайшие функциональные группы, как, например, микросервис для создания PDF-документов для накладных, микросервис для конвертации видео или микросервис, ответсвенный за отзывы клиентов. Часто архитектура приложения отражает организационную структуру и принципы работы компании. Подход с использованием небольших команд успешно применяется в крупных международных корпорациях.

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

Ограничения монолитных приложений из-за их целостности

Монолитные приложения сталкиваются с рядом проблем, связанных с их целостным бинарным пакетом. Во-первых, такой "монолит" обычно устанавливается на одном сервере, и масштабировать его можно лишь "вертикально", увеличивая мощность этого сервера. Этот метод масштабирования имеет свои ограничения, хотя и достаточно высокие. Например, многие банки, включая Альфабанк, используют мощные сервера-мейнфреймы на базе операционной системы HP-UX. Поставщики предлагают обновления серверов в реальном времени, функционал версионирования и высокую скорость обработки данных, однако стоимость и обслуживание таких серверов намного выше, чем при использовании облачных решений. В отличие от этого, микросервисный подход позволяет масштабировать каждый сервис отдельно и "горизонтально", увеличивая количество запущенных экземпляров.

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

Переход к микросервисам

Микросервисы кажутся идеальным решением, но основной их недостаток — это необходимость дополнительных затрат на организацию процессов и настройку развертывания приложения. По этой причине Сэм Ньюмен, автор известной книги "Создание микросервисов", советует начинать с более простых архитектурных решений и переходить к микросервисной архитектуре только после того, как проект докажет свою жизнеспособность и начнет расти.

При переходе от монолитной или сервисно-ориентированной архитектуры к микросервисам компании необходимо предпринять несколько ключевых шагов. Первый шаг — это разделение бизнеса на зоны ответственности, что хорошо описано Эриком Эвансом в его книге "Предметно-ориентированное проектирование (DDD)". Затем нужно назначить команды, которые будут отвечать за эти выделенные сегменты.

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

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

Также возникает необходимость настроить сетевое взаимодействие между существующим монолитом и новым микросервисом. Если микросервис предоставляет данные напрямую клиентам, например, браузерам, то сегодня стандартом является использование формата данных JSON с передачей этих данных по протоколу HTTP. Для внутреннего межсерверного взаимодействия часто используются как JSON, так и оптимизированные Protocol Buffers в сочетании с gRPC/HTTP. Связь между сервисами может быть нарушена в любой момент, и важно заранее разработать стратегии для управления различными сценариями. В этом могут помочь специализированные библиотеки, такие как Polly для Java и .NET. Ключевые стратегии включают повторение запроса в случае определенных ошибок, временную приостановку запросов к микросервису для его восстановления, а также использование альтернативных источников данных, если микросервис временно недоступен.

Также важен вопрос о размещении сервиса. Хотя возможно арендовать собственный сервер и развертывать на нем сервисы, это потребует дополнительных затрат на настройку и поддержку. Современные крупные облачные провайдеры предлагают множество опций, таких как "бессерверные" функции, запуск приложений из zip-архива или Docker-образа, а также Kubernetes-кластеры. Большую часть обслуживания инфраструктуры сервисов берут на себя провайдеры.

С увеличением количества облачных ресурсов удобно использовать Terraform, программное обеспечение, которое позволяет описывать инфраструктуру в виде кода. Эта программа автоматически определяет различия между текущим и желаемым состоянием и разворачивает необходимые облачные ресурсы.

Отдельно необходимо настроить процессы непрерывной интеграции (CI) и, если возможно, непрерывной доставки (CD) для каждого микросервиса. Непрерывная интеграция включает автоматическую сборку приложения при каждом изменении кода, выполнение юнит-тестов и отправку результатов в виде библиотеки или Docker-образа в центральный реестр. Непрерывная доставка подразумевает автоматическое развертывание приложений, проверку с помощью интеграционных тестов и постепенный перевод трафика с действующих серверов на новые. В идеальных условиях разработчики могут добавлять код, покрытый тестами, и через несколько минут видеть результаты в продакшен-сервисе. Для настройки данных процессов часто используются такие инструменты как GitHub Actions, GitLab CI/CD, Jenkins и TeamCity.

Читайте также
Как компаниям эффективно интегрироваться в новые реалии? Как выбрать наиболее удачный отечественный продукт взамен привычных инструментов для управления ИТ-услугами и внутренними процессами?

После развертывания рекомендуется настраивать масштабирование сервиса — увеличивать или уменьшать количество экземпляров в зависимости от загрузки. "Бессерверные функции" предоставляют такую возможность автоматически.

Сбор и анализ логов со всех сервисов централизованно осуществляют такие системы, как Datadog, NewRelic и Splunk. Если за монолитными приложениями ранее могли следить лишь несколько специалистов, то обслуживание микросервисов часто ложится на плечи малых команд. В Amazon, Google и Microsoft разработчики за дополнительную плату попеременно несут дежурство по поддержке своих сервисов.

Вывод

Микросервисная архитектура предоставляет много преимуществ по сравнению с разработкой монолитных приложений и уже достигла стабильной фазы развития, с множеством инструментов, облегчающих работу с ней. Однако настройка и поддержка микросервисов всё ещё требуют значительных усилий и специализированных знаний, что заставляет организации выделять отдельный персонал, именуемый DevOps, для этих целей.

Ссылки:

Опубликовано 19.04.2024

Похожие статьи