Блог

  • Главная Блог Декомпозиция монолита на микросервисы, реальный опыт до Docker, Kubernetes и облаков

Как я распилил монолит на микросервисы, когда никто еще не знал этого слова

На дворе 2007 год. Пока весь мир только присматривается к Web 2.0, а мой проект в виде конструктора сайтов "Интернет-Столица" начинал трещать по швам от собственного успеха. Цифры для того времени были серьезные: 4 000 000 посетителей в год, 500 000 зарегистрированных компаний. По сути, это была огромная ферма. Каждый бизнес получал свой сайт на субдомене городского портала. Большинство жили на бесплатных тарифах, но тысячи клиентов платили за продвинутый функционал.

Как я распилил монолит на микросервисы, когда никто еще не знал этого слова

А функционал сайтов был «жирным»...

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

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

У каждого городского портала был свой домен, а компании данного города получали субдомен вида company.city.ru. Компании регистрировались, чтобы попасть в каталог организаций города, но по факту получали полноценный сайт, к которому можно было припарковать домен второго уровня.

Они наполняли сайт контентом: текстами, фотографиями, картинками. При этом информация о компании автоматически попадала и на сам городской портал. Таким образом, компания получала не просто сайт, а ещё и трафик с портала плюс поисковый трафик по всей сети проектов.

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

Точка невозврата

Сначала я шел классическим путем: «вертикальное масштабирование». Добавлял оперативку, втыкал самые быстрые винчестеры, менял процессоры.

В итоге я собрал самый мощный сервер, который физически можно было впихнуть в корпус 1U. И вот тогда стало понятно, что ресурсы исчерпаны. Один сервер больше не вывезет.

Что было внутри системы

На тот момент в системе управления конструктором сайтов компаний было огромное количество функционала:

  • система резервного копирования;

  • входящая почта;

  • полноценное логирование, т.е. владельцы сайтов могли видеть все события;

  • безопасный режим, который позволял мгновенно отключить виджеты, если пользователь вставил «кривой» JavaScript;

  • визуальный редактор, позволявший создавать тысячи страниц;

  • интернет-магазин;

  • новости с неограниченным объёмом контента;

  • вакансии;

  • фотогалереи с оптимизацией изображений;

  • безопасная загрузка файлов различных типов;

  • конструктор форм с возможностью менять поля, их порядок и тексты ответов;

  • опросы и голосования;

  • подключение внешних данных через фреймы и виджеты.

Шаблоны и автоматическое наполнение

Одной из уникальных возможностей была система шаблонов. Существовало 25 базовых дизайнов, каждый из которых был адаптирован под более чем 100 тематик.

Ты выбирал тематику и сайт сразу получал:

  • подходящий дизайн,

  • тематические картинки,

  • базовую структуру.

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

    Выбираешь шаблон, и сайт сразу выглядит «как надо».

    Система управления сайтом

Генерация уникального контента

Но я пошёл ещё дальше. Задолго до появления современных ИИ я реализовал технологию программирования текстов.

Она позволяла генерировать колоссальные объёмы уникального текстового контента, где вроде бы говорилось об одном и том же, но каждый раз разными словами. Один текст мог быть пересказан миллиардами вариантов.

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

Дополнительные возможности

Также в системе управления сайтом у компаний были:

  • персональные дизайны;

  • гибкая настройка меню и подменю;

  • версия для слабовидящих;

  • праздничные оформления (часто включали перед Новым годом);

  • набор визуальных и звуковых эффектов для маркетинга;

  • парковка доменов;

  • подключение корпоративной почты через Яндекс и Mail.ru;

  • мобильная версия сайта на поддомене m. (адаптивного дизайна тогда ещё не было).

    Система автоматически определяла устройство пользователя и при необходимости перенаправляла на мобильную версию.

    Были сервисы SEO-оптимизации, регистрации в поисковиках, подтверждения прав на сайт, антиспам и антивирусная защита, а также множество тарифных планов, позволявших за небольшие деньги иметь полноценный сайт.

Когда монолит стал проблемой

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

Сделать из этого монолита систему независимых сервисов казалось почти невозможным. Казалось, что проще написать новый проект, чем переделать существующий.

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

Для справки: В 2008 году Amazon и Netflix только-только начнут пробовать дробить свои монолиты. Мартин Фаулер напишет свою знаменитую статью «Microservices» только в 2014-м.

А я сижу у себя в Димитровграде (Ульяновская область), смотрю на эту доску и понимаю, что мне нужно как-то ломать этот веник по соломинке, иначе проект умрет.

Игра в «Бирюльки»

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

Я взял огромную белую маркерную доску и начал рисовать архитектуру «As Is» (как есть сейчас). Моя цель была понять степень связанности компонентов. Я пересмотрел весь код проекта и зарисовал всё на доске. Получилась страшная паутина, где всё зависело от всего.

После этого я начал выделять узлы с наибольшей нагрузкой. Некоторые компоненты тянули систему вниз сильнее остальных.

Я выписал их в порядке убывания нагрузки и начал выносить то, что:

  • было нагружено,

  • имело минимальную связанность,

  • с наименьшей вероятностью могло что-то сломать.

    Собственная система статистики

Что выносилось первым

1. Собственная система статистики. Это был самый «горячий» узел. Все порталы и сайты постоянно дергали его. Я вынес статистику на отдельный сервер и оптимизировал её.

2. Бэкапы. Тяжёлая асинхронная операция, которую тоже полностью отделил.

3. Логирование. Тоже стало отдельным сервисом, чтобы не мешать основной логике.

4. Система дизайнов. Переработал архитектуру так, чтобы после установки дизайн становился независимым от системы шаблонов.

География и поиск

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

Поисковый движок

Отдельно был вынесен поисковый сервер. Это была моя гордость. Elasticsearch появится только через три года, поэтому я «изобрел» свой полнотекстовый поиск.

Он работал мгновенно, учитывал морфологию и склонения на 7 языках. Позже я прикрутил туда парсинг тендеров с zakupki.gov.ru (тогда это еще разрешали делать). Поиск выделился в мощный независимый узел.

Поисковый движок

Система продвижения «Пегас»

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

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

Как это работало без Docker и REST

Тогда я не знал слов SOAP или REST. Я создавал свои протоколы обмена данными. Но уже тогда думал о безопасности: все запросы между моими «микросервисами» сопровождались хэшем с меткой времени. Если кто-то перехватывал запрос http, он не мог его повторить - хэш протухал. SSL/TLS в то время уже стал де-факто стандарт для денег и авторизации, но не для всего сайта.

В итоге всё работало без Kubernetes, без балансировщиков, чисто на логике и самописном автоматическом управлении.

Переход занял ровно год

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

Самое удивительное, что проект работает до сих пор. На тех же технологиях. Последние 12 лет им никто не занимался - классическое «работает - не трогай».

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

Мои выводы по выбору архитектуры

Логическая связанность важнее физической. Даже если вы пишете монолит, делайте «тонкие» контроллеры и выносите логику в сервисы. Низкая связанность - залог того, что завтра вы сможете вынести этот кусок в отдельный микросервис за пару часов.

Делите базы данных логически. Если у вас «деньги» и «контент» лежат в разных БД (пусть и на одном сервере), то никто не сможет сделать между ними JOIN в SQL. И это отлично! Используйте ID для связок, но забудьте про Foreign Keys между разными бизнес-доменами данных. Тогда при масштабировании вам не придется распиливать таблицы «по живому».

Микросервисы - это не мода, а необходимость. Но внедрять их нужно только тогда, когда реально уперлись в потолок ресурсов одного узла.

Интересно было бы взглянуть на ту самую фотографию с маркерной доской 2007 года? Если найду в архивах, то обязательно выложу в следующем посте.

Нужна помощь?

Нужен эксперт для проекта или помощь по вашему направлению? Я готов обсудить возможность сотрудничества