Три дня, ноль простоя: как мы вынесли монолит в микросервисы

AlexPet

New member
Привет, форумчане. Хочу рассказать про проект, который до сих пор вспоминаю с смесью гордости и нервного тика. У нас был монолит на четыреста с лишним тысяч строк, который собирался двадцать минут, а релиз раз в две недели превращался в ночной квест с дежурной пиццей. Классика: одна база, общие модели, любой чих в модуле заказов ронял отчёты, а фраза «давай просто быстро поправим» означала три дня регресса. Задача звучала как вызов из тех, что обычно пишут в вакансиях: перейти на микросервисы за три дня и не уронить прод ни на минуту. Сразу оговорюсь честно, чтобы не было иллюзий: три дня — это про переключение, а не про всю работу. До этого мы почти месяц не спеша готовили почву, и именно эта подготовка сделала финальный спринт скучным, а скучный спринт — это лучший спринт в моей жизни.

Главная мысль, которую я вынес: «без простоя» достигается не героизмом в ночь релиза, а тем, что ты заранее договорился о том, как будешь откатываться. Мы выбрали стратегию постепенной замены: старый монолит остаётся работать, а рядом поднимается новый сервис, и весь трафик идёт через единый вход, который решает, кому его отдать. Никаких «больших взрывов», никакого распила всего сразу. Сначала мы честно ответили себе на вопрос, какой домен болит сильнее всего. У нас это были уведомления и часть биллинга: высокая нагрузка, частые изменения, минимум связей с остальной логикой. Идеальный кандидат на вынос.

Первый день ушёл на каркас. Мы подняли сервис, повторили в нём логику до последней строчки и запустили режим двойной записи: монолит по-прежнему обслуживает пользователей, но параллельно отправляет события в новую систему. Ответы нового сервиса сравнивались со старыми в теневом режиме, и любое расхождение летело в лог с полным контекстом запроса. Это самый недооценённый этап. Все хотят сразу переключать проценты трафика, но пока у тебя нет доказательства, что новый код отвечает так же, переключать нечего. К вечеру первого дня мы уже видели сотни тысяч сравнений и горстку расхождений, каждое из которых было либо багом, либо подарком судьбы в виде давно забытого легаси-костыля.

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

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

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

Теперь конкретные советы тем, кто думает о таком переходе. Не начинайте с трёх дней, начните с одного самого болезненного участка и доведите его до конца: от выноса до полного переключения и, что важнее, до отката. Договоритесь о контрактах между сервисами заранее и покройте их тестами, иначе каждая команда будет жить в своей версии реальности. Поставьте тумблеры до того, как они понадобятся, а не в момент аварии. И обязательно договоритесь с бизнесом о критериях успеха в цифрах: доля ошибок, задержка, время отката. Иначе ваш триумф будет вечным спором о вкусах.

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

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