Автономия и универсальность: как работает микросервисная архитектура
О каких принципах идет речь?
- Модульность — система должна быть разделена на отдельные компоненты, или модули, каждый из которых выполняет определенные функции.
- Связанность — между модулями и компонентами должно быть минимальное количество связей.
- Универсальность — компоненты должны быть созданы так, чтобы их можно было повторно использовать, но уже в других проектах.
- Абстракция — при проектировании необходимо руководствоваться «методом черного ящика», который позволяет фокусироваться на функциональности компонентов без погружения в детали их внутреннего устройства.
- CI/CD (непрерывная интеграция и доставка) — процесс сборки, тестирования и развертывания программного обеспечения должен быть автоматизирован.
Цифровые услуги — от получения паспорта до стриминговых площадок с музыкой и видео или доставки еды на дом — делают жизнь ярче и динамичнее. Но к хорошему сервису человек быстро привыкает, воспринимает его стабильную работу как данность, а в случае проблем, например регулярных ошибок или медленной загрузки, начинает искать альтернативу.
И, с одной стороны, разработчики постоянно расширяют функционал своих сервисов, чтобы удерживать интерес пользователей, а с другой — должны поддерживать их стабильную работу. Но между этими задачами есть противоречие: появление новых функций неизбежно влияет на стабильность работы, и владельцу сервиса необходимо уметь управлять сложностью своего продукта.
Разработчики заговорили об этой проблеме в начале 1960-х. А в 1968 году на конференции по программному обеспечению (ПО) в Гармиш-Партенкирхене эксперты предложили ряд идей, которые легли в основу отдельной дисциплины — «программная инженерия». Она состоит из принципов, помогающих разработчикам заниматься созданием ПО, соблюдая заданные сроки и бюджет.
Если следовать этим принципам, то с ростом нагрузки и ограничений в виде физических возможностей оборудования, практически любое решение проходит путь от монолитной структуры к микросервисной.
Это связано с тем, что при коллективной работе над модулями в рамках одного репозитория (места, где хранятся данные) кода удерживать область ответственности каждого модуля становится очень трудоемкой и дорогой задачей. Внесение любого изменения требует тщательной верификации участниками команды разработки и архитекторами, в процессе чего возникает много коммуникаций, в основе которых лежит субъективное мнение о том, какие функции следует включать в состав каждого модуля.
Когда время поставки изменений падает до критического уровня, единый репозиторий кода разделяют на несколько репозиториев, каждый из которых отвечает за один модуль, а протоколы взаимодействия между модулями фиксируются в контрактах. За каждым репозиторием назначают ответственного за его функционал, ограничивая остальные команды в правах на внесение изменений в его функциональность.
Такой же процесс происходит со структурой базы данных. Каждый модуль нуждается в своей структуре, и все команды приходят к состоянию, когда каждый модуль работает со своей структурой, не зависящей от остальных модулей.
В итоге у каждого модуля формируется собственная команда разработки с собственным списком задач и релизным циклом. При правильно разработанных KPI для модульных команд каждая из них начинает стремиться минимизировать зависимости от других команд, самостоятельно находя баланс между зависимостью от функционала чужих модулей и скоростью поставки изменений.
Разумеется, это вызывает рост накладных расходов на управление, сборку и развертывание конечного решения, в связи с чем возникает потребность в изменении производственных процессов и автоматизации рутинных операций. Запрос на внедрение лучших практик DevOps появляется естественным образом, и это не вызывает отторжения у участников модульных команд.
Первыми этот путь прошли компании, которые ежедневно сталкиваются с проблемами в работе высоконагруженных и крайне сложных систем. В процессе своей работы они постепенно разрабатывали и унифицировали целый набор инструментов и технологий. А после того как они опубликовали свои наработки под открытой лицензией, возможность использования микросервисов стала доступной в средних, а иногда и в малых проектах, что привело к ее широкому распространению. Это подтверждает исследование, и которого следует, что 77% опрошенных компаний уже используют микросервисную архитектуру, при этом каждая шестая переносит от 75 до 100% своих система на микросервисы.
В России тоже достаточно примеров. Так, крупный российский ритейлер давно развивает собственную микросервисную архитектуру для оптимизации электронной коммерции и повышения гибкости разработки. Из тех же соображений на микросервисную архитектуру перешел другой крупный онлайн-ритейлер, что позволяет ему регулярно обновлять отдельные функции платформы, не подвергая риску другие части системы. «Лаборатория Касперского» активно использует микросервисную архитектуру, что позволяет повысить надежность и масштабируемость продуктов, а также облегчить процесс их улучшения и обогащения новыми функциями.
Преимущества и недостатки
Переход с монолитного решения на микросервисы дает еще несколько преимуществ.
Самой серьезной считается проблема синхронизации данных между компонентами. Используя микросервисный подход, мы получаем распределенную систему. Вместо единой транзакции, которая происходила в монолитной структуре, на одну бизнес-операцию выполняется множество микротранзакций внутри отдельных микросервисов. Для некоторых типов систем такое поведение просто недопустимо, а в остальных случаях нужно учитывать альтернативные сценарии для обработки отказов, которые могут произойти в цепочке распределенных вызовов. И чем больше транзакций происходит в рамках одной бизнес-операции, тем сложнее становится разработка.
Как понять, что компании это нужно
Если вы задумались о переходе к микросервисной архитектуре, то надо честно ответить на следующие вопросы:
Первое связано со снижением времени, которое требуется разработчику для того, чтобы разобраться с устройством микросервиса и начать приносить пользу команде. В случае со сложным монолитным решением на это требуется существенно больше времени.
Также использование микросервисов несет дополнительные издержки на оборудование и работы. Построение конвейера сборки и развертывания на основе kubernetes требует, по нашим наблюдениям, минимум семь серверов (в каждом 24 ядра CPU и 24GB ОЗУ) и двух инженеров на полную ставку, обладающих компетенциями в администрировании и разработке. При этом в состав оборудования не входят мощности для подсистемы хранения (СУБД, Ceph, S3 и тд.) и подсистемы очередей (Kafka, Rabit MQ и тд.).
- Достигла ли стоимость масштабирования за счет увеличения мощности «железа» физического или финансового потолка?
- Разрослась ли структура монолитного решения до размеров, когда ни один участник команды не в состоянии предсказать, какой будет результат после внесения изменения, а падения при каждом релизе стали нормой?
- Вы не можете обновлять свой технологический стек, так как есть блокеры в виде компонентов, которые не могут работать на новых версиях фреймворков?
- Вы стали зависимы от одного или нескольких вендоров, чьи проприетарные решения стоят в основе вашего ИТ-ландшафта?
- План выхода релизов растянулся во времени и перестал успевать за запросами рынка?
Второе и третье преимущества перехода на микросервисы дают технологии оркестрации: возможность динамически масштабировать систему путем клонирования сервисов и автоматического запуска нового экземпляра в случае падений идет «из коробки». Причем оркестратор берет на себя и распределение нагрузки между ними.
При каждом положительном ответе постарайтесь оценить его влияние на бизнес, и если совокупные потери превышают стоимость перехода, то пришло время начинать. Как было сказано выше, это естественный процесс развития, и вы можете себя поздравить с тем, что насупило время и вам пройти этот сложный путь к новому уровню свободы, доступности, производительности и скорости развития.
Разумеется, помимо всех достоинств, микросервисная архитектура обладает и рядом крупных недостатков.