Микросервисы: плюсы, минусы, когда и зачем внедрять
Чем быстрее идея воплотится в новый проект, тем больше шансов занять нишу, завоевать лояльность пользователей и, как следствие, стать успешнее конкурентов. Ускорить разработку и сделать её более гибкой и управляемой помогает микросервисная архитектура. Вместе с Дмитрием Горчаковым, руководителем отдела разработки РЕД-СОФТ, мы разобрали плюсы и минусы микросервисов, а ещё рассмотрели сценарии, как компании приходят к их внедрению.
Что такое микросервисная архитектура
Большинство проектов, особенно стартапов сначала выбирают монолит, так как нужен быстрый старт при минимальных ресурсах и не ясны перспективы. Но с увеличением размеров и сложности приложения управлять монолитом становится всё труднее. Любое изменение в монолитном приложении может иметь каскадный эффект, оказывая влияние на другие части приложения, что существенно усложняет интеграцию и развертывание в промышленной системе. Также присутствует риск отказа всего приложения в случае ошибки или деградации производительности модуля.
Альтернатива монолиту — микросервисы.
Микросервисная архитектура — один из подходов проектирования, при котором единое приложение строится как набор небольших сервисов. Каждый модуль работает в собственном процессе и взаимодействует с другими модулями. Модули работают независимо и построены вокруг бизнес-потребностей и выполняют определённую функцию. Например, хранят данные пользователей или отвечают за аутентификацию.
Впервые о микросервисах заговорили ещё в 2000-х годах, когда в США произошёл кризис электронных технологий. Тогда был бум на интернет-сервисы, но никто всерьёз не задумывался о масштабировании, а оборудование не было таким мощным. В один момент крупные сервисы не смогли справиться с возросшей нагрузкой и потеряли своих пользователей и инвестиции. Это привело к переоценке многих вещей в индустрии ПО, и уже к началу 2010-х микросервисы сформировались как концепция архитектуры. А к 2014-ому их начали внедрять крупные компании вроде Netflix, Amazon и Twitter.
Минусы микросервисного подхода
При кажущейся простоте и логичности деление большого монолитного приложения на самостоятельные сервисы — сложная техническая задача. Сам микросервисный подход не лишён недостатков, а его плюсы могут оборачиваться минусами:
Сложнее осуществлять мониторинг. Монолит один, и отслеживать, как он работает проще. Микросервисов сотни, а иногда тысячи, и уследить за каждым физически невозможно. Поэтому приходится уделять много внимания системам управления и мониторинга.
Каждый микросервис может использовать тот язык программирования и те технологии, что удобны команде, которая его разрабатывает. С одной стороны, это плюс — какие-то фреймворки и языки лучше заточены под конкретные вещи. Если мы делаем сервис обработки изображений или машинного обучения, можем не заострять внимание на технологиях монолита, а выбрать решение под задачу. С другой стороны, это минус — нужно как-то конфигурировать все микросервисы между собой и поддерживать «зоопарк» технологий.
Снижение доверия. Когда у нас сотни узлов, могут возникать проблемы с аутентификацией и авторизацией, поскольку есть вероятность подсоединения мошенников.
Сложности развёртывания. Чтобы требования по отказоустойчивости выполнялись, микросервисы нужно развёртывать на отдельных серверах. И здесь не работает подход: «Берём приложение, ставим и запускаем». Нужны системы оркестрации и деплоймента.
Плюсы микросервисного подхода
Один из основных плюсов микросервисов — повышение показателей доступности и отказоустойчивости. Когда монолит падает, он полностью перестаёт работать. В приложении с микросервисной архитектурой перестаёт работать только какая-то часть. Например, в интернет-магазине может сломаться корзина, но клиенты без проблем продолжат пользоваться каталогом, добавлять товары в избранное и т.д.
Ещё один плюс — повышение надёжности. Предположим, начинающий разработчик залил непроверенные изменения в прод. В случае с монолитом всё сразу упадёт, а с микросервисом сломается только участок системы, остальное будет работать.
Также важно, что в приложении с микросервисной архитектурой локализуются сложность и риски отказов, а производительность системы масштабируется по горизонтальному пути. Компоненты (узлы) автономны, а значит легче поддаются тестированию.
Как компания понимает, что пора внедрять микросервисы
Глобально можно выделить два подхода к разработке приложений. Первый — когда зрелая компания с опытным архитектором и командой разработки решает написать сервис, который будет выдерживать большие нагрузки. В этом случае уже есть понимание, что монолит не справится с поставленной задачей, нужен другой архитектурный подход. Примеры — «ВКонтакте», «Одноклассники», Mail.ru. Когда они планируют новые продукты, уже понимают, как будут их строить.
Второй подход — когда нужно быстро что-то написать и выкатить, чтобы начать доставлять фичи пользователям. В этом случае мы не знаем, выстрелит проект или нет, поэтому делать сразу микросервисы — оверинжиниринг. Обычно ждут первых результатов, а затем уже принимают архитектурные решения.
Признаки, что пора внедрять микросервисную архитектуру:
Рост нагрузки. У любого монолита есть предел масштабирования, так как он стоит на одной машине. Конечно, машины можно докупить, но эта опция не бесконечна и довольно затратна. Рост стоимости здесь не линеен, и в конечном счёте приведёт к пределу. Скажем, процессор в два раза мощнее, будет стоить не в два, а в четыре раза дороже.
Рост системы. Пользователи добавляются медленно, нагрузка не увеличивается, но фич добавляется всё больше, и постепенно система становится огромной и неповоротливой. Копится технический долг, кодовая база растёт, сложнее добавлять новые функции и при этом ничего не ломать. Разработка становится дороже.
Градация в данных. Появляется какой-то модуль, доступ к которому должен быть быстрее, чем к остальным. Например, мы хотим, чтобы в интернет-магазине доступ к популярным товарам стал быстрее. Делать быстрее доступ ко всем данным (корзине, каталогу и др.) слишком дорого. Вместо этого мы можем выделить под популярные товары отдельный микросервис. Он будет строиться на других технологиях и позволит ускорить доступ.
Появление новых задач. Приходит продакт и говорит, что нужно внедрить машинное обучение. Однако у разработчиков нет соответствующих компетенций для решения этой задачи. Нанимается отдельная команда дата-саентистов, и она пишет микросервис в отдельном репозитории, используя свой стек технологий и специальное оборудование.
Как перейти на микросервисы
Процесс разделения целого приложения на отдельные составляющие довольно сложный. Никто не даст вам время, чтобы разрушить монолит и затем спроектировать микросервисную архитектуру — это противоречит требованиям бизнеса. Разделение должно быть незаметно для пользователей и проходить в несколько этапов, когда работает монолит, а данные постепенно мигрируют в микросервисы.
Каких-то академических подходов к «распиливанию монолита» нет. Всё зависит от особенностей системы и поставленной задачи. Предположим, мы хотим выделить систему подписок в монолите. Вот один из сценариев, как это может быть:
Шаг 1. Выделяем отдельный узел и переносим туда логику. При необходимости делаем рефакторинг кода общей системы, чтобы она была меньше связана с другими модулями, а мы могли вынести её в отдельный узел. Разрабатываем способ взаимодействия.
Шаг 2. Живём «двойной жизнью», пока данные реплицируются. Убеждаемся, что всё работает правильно.
Шаг 3. Полностью отключаем функциональность от монолита и переносим её на микросервисы.
По такому же принципу можно работать и с другими функциональными модулями монолита.
Пример микросервиса Java
Сейчас я пишу учебный проект для курса Слёрма — сервис обмена валюты. И здесь явно присутствует разбиение на несколько узлов: сервис авторизации, модуль котировок, который показывает, сколько стоит валюта, модуль процессинга, где происходит обмен, историю и оповещения.
Всего пять модулей, но чтобы эти пять модулей правильно работали, добавляются ещё обслуживающие модули:
модуль маршрутизации, который будет управлять запросами;
балансировщик нагрузки, который будет следить, чтобы модель котировок не отказывала;
service registry, который поможет команде понять, какие сервисы есть, как работают, какие порты слушают и т.д.;
сервис конфигураций, который будет конфигурировать наши пять модулей;
сервис логирования и журналирования, который поможет быстро обнаруживать проблемы;
сервис трассировки, который позволит определить, где сейчас запрос;
сервис сбора метрик, который покажет, что и как у нас работает, какие бизнес-параметры выполняются.
То есть помимо пяти сервисов, которые выполняют какую-то полезную работу, нам нужны ещё узлы, которые будут играть обслуживающую роль.
Вместо заключения: частые ошибки при работе с микросервисами
Разбивая приложение на микросервисы, разработчики нередко допускаются одни и те же ошибки. Например, забывают о переходном периоде, из-за чего возникает ситуация, когда микросервисы ещё не готовы, а монолит уже упал. Или не заботятся об обслуживающих сервисах. Скажем, без метрик разобраться, что именно сломалось, будет очень сложно. И придётся потратить немало времени, чтобы найти проблему, так как запросы могут путешествовать по разным узлам. Многие бросаются сломя голову внедрять микросервисный подход, игнорируя такие вещи, из-за чего впоследствии возникают серьёзные проблемы. Разделять сложнее, чем объединять, и такому архитектурному рефакторингу подвержены только грамотно написанные и спроектированные модули.
Для тех, кто хочет разобраться в микросервисах
15 июля у нас стартует курс »Микросервисы и API на Java и Kotlin». Вы узнаете, как писать микросервисы и работать с приложениями на одних из самых популярных языков программирования. Познакомитесь с Java-фреймворком для разработки модулей микросервисов Spring Boot и прочими полезными инструментам и подходами.
Посмотреть программу и записаться