Хабрахабр

[Из песочницы] Микросервисы или монолит: ищем решение

image

Когда задумывается большой продукт или маленький софт начинает вырастать в левиафана, какой путь развития выбрать? Стоит ли все переписывать с нуля или продолжать «исторически сложившиеся» традиции? Да и вообще, стоит ли пересматривать саму концепцию архитектуры?

Меня зовут Константин, и я являюсь ведущим разработчиком одной довольно крупной системы, которая начиналась когда-то как эксперимент. Здравствуйте, хабровчане! Шло время, сайт рос и столкнулся с рядом проблем, решение которых поставило вопрос «а дальше-то как?».
Монолит или микросервисы? Небольшой сайт на PHP, созданный буквально «на коленке» и, конечно же, монолитом. Базовое отличие подходов, на мой взгляд, состоит в том, что монолит подразумевает централизованный цикл обработки запроса пользователя, а микросервисы — децентрализованный. Что же выбрать? Однако есть и не столь явные и очевидные факторы, влияющие на выбор архитектуры. Общие достоинства и недостатки обоих подходов широко известны и не раз перечислены (например, тут, тут или тут).

  1. Загрузка штатных сотрудников. При бурном развитии продукта накапливается пул задач, решить которые в приемлемые сроки нельзя — все заняты. И если такой «завал» единичен, расширять штатный состав разработчиков не имеет смысла. Очевидное решение — внешние подрядчики (компании или фрилансеры). Но как отдать им в работу фрагмент продукта, не рискуя превратить его в OpenSource, грубо говоря? В случае использования микросервисов такую задачу решить гораздо легче.
  2. Сложность погружения. Чем больше продукт, тем больше времени требуется новому сотруднику, чтобы освоиться в нем. Особенно, если в коде много различных умолчаний (да, хорошее документирование существенно облегчает процесс, но если его нет?) и кастомизаций для отдельных частных случаев. С этой точки зрения разобраться с небольшой независимой частью гораздо легче, чем с целым продуктом сразу.
  3. Ресурсы при пиковых нагрузках. В моей практике был случай, когда нагрузка на серверах иногда вырастала до неприемлемых значений (а если конкретно — исчерпывалась ОЗУ, задействовался своп и сервер превращался на время в овощ), при свободной работе все остальное время (загрузка составляла не более 30% по показателю ОЗУ). И такие пики случались нерегулярно и с большими паузами. В случае монолита (считаем, что оптимизировать код уже некуда) спасает только подключение новых серверов с копией всей системы для распределения нагрузки. А в случае микросервисов можно организовать очередь обработки (конечно, это применимо только для некритичных по времени операций, которые быстро и не ожидаются, вроде выгрузки таблицы Excel).
  4. Выполнение задач в «фоновом» режиме. В какую сторону этот фактор «качает лодку», зависит от его величины и сложности. Как правило, достаточно монолита и таймера (cron). Но если задачи начинают скапливаться в большие группы, появляются и проблемы. Надо балансировать уже и cron-задачи. Микросервисы существенно облегчают такую ситуацию.
  5. Сложность сопровождения. В случае микросервисов повышаются требования к сопровождению железа — где, что и как должно быть настроено. Монолит — грубо говоря, одни настройки на все ноды, микросервисы — настройки зависят от требований конкретных микросервисов, которые на ноде запущены.
  6. Требования к квалификации. Чем больше зоопарк технологий (а он, как правило, растет, если система микросервисная), тем выше требования к навыкам и знаниям штатных сотрудников. Ведь случись доработки или проблемы, они должны справиться. Или же нужно больше специалистов — для покрытия всего стека.

А надо ли вообще выбирать? Стоит ли игра свеч? Я думаю, безусловно, стоит. Но подходить к вопросу надо с холодной головой. Иначе одни проблемы просто заменятся на другие.

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

Сразу строить межкомпонентные связи так, как будто эти компоненты уже (или почти уже) «внешние сервисы». Проектируя стартовый монолит, возможности дальнейшего подключения внешних сервисов нужно заложить сразу. Особенно, если они ресурсоемкие.

Например, обеспечить общий доступ к сессии пользователя. Сразу же продумать политику работы с кешами и хранилищами данных (БД и файлы).

Для себя я вывел следующую формулу хорошего проекта: «эффективная система — это сбалансированная система». И самое главное — не кидаться в крайности. И то, только при выполнении хотя бы одного из условий: В частности, это выражается в том, что в микросервисы я выношу только большие, логически обособленные фрагменты ядра.

  1. требуется ограничение и прогнозирование нагрузки, задержка по времени из-за выполнения задач поочередно не является критичной
  2. обособление даст значительный прирост производительности.

Как результат такого подхода получилась система, 95% функционала, которой располагается в ядре, и 5% — в микросервисах. Но при этом на ядро приходится только 60% всей нагрузки. И при этом можно гарантировать, что нагрузка на отдельные сервера не превысит критических значений.

Есть большие продукты, которые успешно живут монолитом. Так что микросервисы — это (с определенного размера продукта) хорошо, если использовать их только в случае реальной необходимости, а не в силу моды или «потому что круто». Но иногда монолитом задачу не решить…

Спасибо!

Теги
Показать больше

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

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть