Alex.Miller
New member
За последние десять лет я успел поработать и тимлидом в двух быстрорастущих стартапах, и приходящим консультантом в командах, у которых внезапно поехала нагрузка. И знаете что? Почти всегда причина была не в том, что кто-то плохо писал код. Причина была в архитектурных решениях, принятых на этапе, когда команда из трёх человек гналась за первым платящим клиентом. Ниже пять ошибок, которые я встречал чаще всего, и одна из них однажды стоила мне трёх месяцев переписывания бэкенда.
Ошибка первая: монолит без границ. Монолит сам по себе не зло, я до сих пор считаю его лучшим стартом. Проблема начинается, когда внутри него нет модульных границ: бизнес-логика платежей лежит рядом с рассылкой, модели заказов напрямую тянут таблицы пользователей, а любой рефакторинг превращается в русскую рулетку. Мы так жили полтора года, и когда решили выделить биллинг в отдельный сервис, оказалось, что он прошит зависимостями в сорока местах. Совет простой: даже в одном репозитории держите жёсткие границы модулей и не давайте им лазить друг другу в таблицы. Дешевле не бывает.
Ошибка вторая: преждевременные микросервисы. Как только инвестор сказал слово масштабирование, половина знакомых мне команд побежала дробить систему на двадцать сервисов с Кафкой, сагами и распределёнными транзакциями. Итог обычно печальный: продукт не успевает меняться, потому что на каждую фичу нужно согласовать пять контрактов, а отладка одного запроса занимает день. Я через это проходил и вернулся назад. Микросервисы оправданы, когда у вас есть команды, которые физически мешают друг другу, а не когда вам просто страшно смотреть в будущее.
Ошибка третья: одна база как общая свалка. У нас был PostgreSQL, к которому ходили все: веб, мобильное API, аналитика, ночные выгрузки в CRM и админка основателя. Когда база начала задыхаться, выяснилось, что никто не знает, какие запросы самые тяжёлые, потому что их никто не логировал. Классика. Разделяйте роли и права доступа сразу, выносите аналитику на реплику, ставьте лимиты на тяжёлые запросы и ведите учёт того, кто и зачем ходит в каждую таблицу. Это скучно, но именно скучные вещи спасают вас на пике.
Ошибка четвёртая: всё через синхронный HTTP. Пока у вас сто пользователей, вызов внешнего API прямо в обработчике запроса — нормально. Когда их становится сто тысяч, один медленный партнёрский сервис кладёт всю вашу страницу оформления заказа. Я видел, как падала выручка из-за того, что чужой вебхук отвечал по восемь секунд, а мы ждали его в блокирующем вызове. Учитесь асинхронности раньше, чем она станет обязательной: очереди, ретраи с экспоненциальной задержкой, идемпотентность операций и таймауты везде, где есть сеть.
Ошибка пятая: отсутствие наблюдаемости и плана миграций. Схему меняли руками в продакшене, бэкапы делались, но никто ни разу не проверял, восстанавливаются ли они, метрик не было вообще, а о падении узнавали от клиентов в поддержке. Стыдно вспоминать, но это мой личный опыт. Пока система маленькая, кажется, что логи и метрики — роскошь. На самом деле это единственный способ понять, что с вами происходит, когда продукт внезапно вырастет в десять раз за месяц.
Что бы я посоветовал читателю? Не гонитесь за модными паттернами, гонитесь за понятными границами и предсказуемыми операциями. Пишите архитектурные решения в виде коротких заметок: что выбрали, почему и при каких условиях пересмотрим. Это спасает от бесконечных споров через полгода. Держите миграции базы в коде и проверяйте восстановление из бэкапа хотя бы раз в квартал. И самое главное — проектируйте под следующую ступень роста, а не под ту, что была год назад, но и не под миллиард пользователей сразу. Масштабирование — это не про технологии, а про способность менять решение без остановки бизнеса.
А теперь вопрос к вам, форумчане: какая архитектурная ошибка из вашего прошлого оказалась самой дорогой — и что вы сделали, чтобы вытащить проект? Очень хочется собрать здесь коллективный опыт, потому что уверен, у каждого за плечами есть история, которая спасла бы другого от пары месяцев боли.
Ошибка первая: монолит без границ. Монолит сам по себе не зло, я до сих пор считаю его лучшим стартом. Проблема начинается, когда внутри него нет модульных границ: бизнес-логика платежей лежит рядом с рассылкой, модели заказов напрямую тянут таблицы пользователей, а любой рефакторинг превращается в русскую рулетку. Мы так жили полтора года, и когда решили выделить биллинг в отдельный сервис, оказалось, что он прошит зависимостями в сорока местах. Совет простой: даже в одном репозитории держите жёсткие границы модулей и не давайте им лазить друг другу в таблицы. Дешевле не бывает.
Ошибка вторая: преждевременные микросервисы. Как только инвестор сказал слово масштабирование, половина знакомых мне команд побежала дробить систему на двадцать сервисов с Кафкой, сагами и распределёнными транзакциями. Итог обычно печальный: продукт не успевает меняться, потому что на каждую фичу нужно согласовать пять контрактов, а отладка одного запроса занимает день. Я через это проходил и вернулся назад. Микросервисы оправданы, когда у вас есть команды, которые физически мешают друг другу, а не когда вам просто страшно смотреть в будущее.
Ошибка третья: одна база как общая свалка. У нас был PostgreSQL, к которому ходили все: веб, мобильное API, аналитика, ночные выгрузки в CRM и админка основателя. Когда база начала задыхаться, выяснилось, что никто не знает, какие запросы самые тяжёлые, потому что их никто не логировал. Классика. Разделяйте роли и права доступа сразу, выносите аналитику на реплику, ставьте лимиты на тяжёлые запросы и ведите учёт того, кто и зачем ходит в каждую таблицу. Это скучно, но именно скучные вещи спасают вас на пике.
Ошибка четвёртая: всё через синхронный HTTP. Пока у вас сто пользователей, вызов внешнего API прямо в обработчике запроса — нормально. Когда их становится сто тысяч, один медленный партнёрский сервис кладёт всю вашу страницу оформления заказа. Я видел, как падала выручка из-за того, что чужой вебхук отвечал по восемь секунд, а мы ждали его в блокирующем вызове. Учитесь асинхронности раньше, чем она станет обязательной: очереди, ретраи с экспоненциальной задержкой, идемпотентность операций и таймауты везде, где есть сеть.
Ошибка пятая: отсутствие наблюдаемости и плана миграций. Схему меняли руками в продакшене, бэкапы делались, но никто ни разу не проверял, восстанавливаются ли они, метрик не было вообще, а о падении узнавали от клиентов в поддержке. Стыдно вспоминать, но это мой личный опыт. Пока система маленькая, кажется, что логи и метрики — роскошь. На самом деле это единственный способ понять, что с вами происходит, когда продукт внезапно вырастет в десять раз за месяц.
Что бы я посоветовал читателю? Не гонитесь за модными паттернами, гонитесь за понятными границами и предсказуемыми операциями. Пишите архитектурные решения в виде коротких заметок: что выбрали, почему и при каких условиях пересмотрим. Это спасает от бесконечных споров через полгода. Держите миграции базы в коде и проверяйте восстановление из бэкапа хотя бы раз в квартал. И самое главное — проектируйте под следующую ступень роста, а не под ту, что была год назад, но и не под миллиард пользователей сразу. Масштабирование — это не про технологии, а про способность менять решение без остановки бизнеса.
А теперь вопрос к вам, форумчане: какая архитектурная ошибка из вашего прошлого оказалась самой дорогой — и что вы сделали, чтобы вытащить проект? Очень хочется собрать здесь коллективный опыт, потому что уверен, у каждого за плечами есть история, которая спасла бы другого от пары месяцев боли.