03 мар. 2025 г.·7 мин чтения

Дрейф архитектуры: 3 признака, что система распадается

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

Дрейф архитектуры: 3 признака, что система распадается

Как выглядит дрейф архитектуры в реальной работе

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

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

Большинство команд не делают это нарочно. Одна команда добавляет кеш, чтобы исправить задержки. Другая держит старую задачу, потому что миграция кажется рискованной. Дедлайн толкает к одностороннему решению в одном сервисе, затем появляется второй обход, чтобы поддержать первый. Каждое решение кажется небольшим и локальным. Вместе они меняют всю систему.

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

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

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

Отсроченная боль делает дрейф лёгким для игнорирования. Система не падает при первом странном решении. Она падает после десятков мелких решений, накопившихся до того, как изначальная структура перестала соответствовать бизнесу.

Дублирующие системы начинают делать одну и ту же работу

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

Выглядит второй инструмент безобидно сначала. Новая очередь обрабатывает упавшие задания, потому что старую сложно дебажить. Новая админка помогает службе поддержки работать быстрее, потому что старая постоянно ломалась. Таблица в гугл‑шите отслеживает статус клиента, потому что никто больше не доверяет полю в базе.

Некоторое время обе системы кажутся полезными. Потом они начинают выполнять одну и ту же работу.

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

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

Цена проявляется позже. Кто‑то пишет джоб синхронизации, чтобы держать записи согласованными. Другая команда добавляет ручную проверку перед релизом. Саппорт начинает спрашивать инженеров, какой экран правильный. Небольшие передачи накапливаются, и каждая добавляет ещё одно место, где данные могут расходиться.

Простой пример показывает проблему чётко. Саппорт меняет подписку в старой админке, в то время как биллинг читает данные из новой. Ночная синхронизация пытается согласовать оба источника. Одно поле мапится неправильно, и клиент видит один статус в приложении, финансы — другой, и никто не понимает, какой из них должен запускать счёт.

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

Простой признак: спросите «Какая система побеждает, если данные расходятся?». Если ответ «зависит» или «проверьте оба», проблема уже реальна.

Когда команда привыкает к дублированию, каждое изменение замедляется. Вы тестируете дважды, объясняете дважды и исправляете баги дважды. Авария может прийти позже, но путаница начинается намного раньше.

Одноразовые исключения становятся нормой

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

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

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

То же происходит с рабочими процессами продукта. Один клиент пропускает стандартный шаг утверждения. Другому нужно копировать данные в отдельную систему. Саппорт вырабатывает специальный процесс для обоих случаев, и новые участники команды наследуют правила, которые существуют только потому, что никто их не убрал.

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

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

Никто не владеет полным потоком

Системы редко ломаются внутри одной аккуратной границы команды. Они ломаются в щелях между ними. Продукт определяет поведение, инженерия выпускает код, опс следит за доступностью, а саппорт слышит жалобы. Если никто не владеет полным путём клиента, дрейф архитектуры растёт тихо.

Это видно, если картировать, где у каждой команды заканчиваются обязанности. Продукт часто ограничивается требованиями. Инженеры — деплоем. Опс — здоровьем сервиса. Саппорт — закрытием тикета. Звучит аккуратно, но реальные проблемы туда не укладываются.

Повторная попытка оплаты — хороший пример. Саппорт видит двойные списания. Инженеры говорят, что API вернул 200. Опс говорит, что серверы были в порядке. Продукт говорит, что правило биллинга требует решения. Между тем никто не решает, кто исправит неверные данные, кто изменит логику повторных попыток и кто будет отвечать на оповещение, если это повторится.

Общая ответственность звучит справедливо. На практике это часто означает, что у никого нет полномочий принять окончательное решение. Люди обсуждают, добавляют комментарии и ждут, кто‑то начнёт первым. Система продолжает работать «достаточно», и зазор остаётся открытым.

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

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

Задайте один простой вопрос: кто владеет этим потоком от начала до конца?

Если один человек или команда владеет им, можно ожидать решений, последовательных действий и меньше недоделок. Если ответ превращается в три имени команд и длинную цепочку в чате — у вас не общая ответственность, а пустое место в системе, и дрейф в таких пустотах растёт быстро.

Простой пример из команды растущего продукта

Find Your Drift Points
Review the flow that keeps breaking and decide what to remove first.

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

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

Через месяц крупный клиент просит одно специальное правило: счета должны ждать ручного одобрения перед списанием. Команда добавляет флаг enterprise_hold. Он обходит обычный шаг от триала к оплате и толкает такие аккаунты в боковую очередь, которую понимают только финансы и один бэкенд‑инженер. Клиент доволен. Флаг не снимают.

Теперь проследите за одной девушкой через систему. Она регистрируется в понедельник, апгрейдится во вторник и открывает тикет в среду, потому что с её карты списали дважды. Саппорт смотрит админку и видит один аккаунт. Биллинг видит две записи клиента. Платёжный процессор показывает одно списание и одну ожидающую повторную попытку.

Потом начинается авра. Сервис promo checkout повторно шлёт вебхук после таймаута. Оригинальный биллинг‑сервис тоже обрабатывает тот же апгрейд, потому что путь enterprise_hold пропустил проверку на дупликаты. Возвраты не проходят, так как инструмент саппорта читает из auth, а не из billing. Логи указывают на три места. Дашборды показывают два ID клиента для одного человека. Ответственность разделена между продуктом, финансами и бэкендом.

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

Как проверить дрейф шаг за шагом

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

Начните с бизнес‑путей, которые сильнее всего страдают при сбое. Для продуктовой команды это может быть путь от регистрации до первой оплаты, лид до предложения или баг‑репорт до исправления в проде. Если путь касается дохода, доступа клиента или нагрузки на саппорт — проверьте его первым.

  1. Выберите два–три пользовательских потока, которые наиболее важны. Не картируйте всё. Короткий список сохраняет фокус и делает слабые места видимыми.
  2. Нарисуйте каждый поток от начала до конца. Включите приложения, базы данных, очереди, дашборды, таблицы, скрипты и людей, которые вмешиваются вручную.
  3. Отметьте каждое место, где одни и те же данные живут в двух местах, где побочные скрипты обновляют записи или где кто‑то выполняет ручное исправление после сбоя основного процесса.
  4. Назначьте одного владельца для каждого шага. Указывайте человека или команду, а не отдел. Если никто не хочет брать шаг — это уже проблема.
  5. Обведите каждое исключение без даты окончания. Временные правила часто остаются годами и тихо превращаются в нормальный путь.

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

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

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

Если ваша карта заканчивается тремя вопросительными знаками и сообщением в Slack «кто за это отвечает?», вы нашли место, с которого начать исправление.

Ошибки, которые скрывают настоящую проблему

Get a Second Technical View
Ask Oleg to map the real production path and spot drift your team stopped seeing.

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

Ещё одна распространённая ошибка — мерить только качество кода. Команды отслеживают покрытие тестами, lint‑ошибки и скорость пулл‑реквестов, но игнорируют сползание процессов вокруг продукта. Если три команды используют разные способы перемещения одних и тех же данных клиента, чистый код не спасёт ситуацию. Система всё равно будет дрейфовать, потому что работа вокруг кода продолжит раскалываться.

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

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

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

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

Быстрый чек‑лист перед следующим инцидентом

Bring in a Fractional CTO
Work with Oleg on architecture, incident follow-up, and product decisions.

Проведите эту проверку на 30‑минутной встрече команды, не во время аварии. Вам нужны спокойные ответы, а не предположения, сделанные под временем и алертами.

Дрейф часто прячется в работе, которая кажется нормальной. Команда приспосабливается, добавляет по одному исправлению за раз и замечает закономерность только тогда, когда релиз ломает что‑то далеко от изменения.

Используйте эти проверки и фиксируйте ответы:

  • Попросите одного человека проследить запрос клиента от первого клика до финальной записи в базе, очереди и уведомления. Если этому человеку нужно несколько передач, у вас слабое общее понимание.
  • Ищите одно и то же бизнес‑состояние в двух местах. Частые примеры — статус аккаунта, правила ценообразования или права пользователя, которые хранятся и в базе приложения, и во внешней админ‑панели.
  • Найдите все обходы, которые должны были быть временными. Если патч, скрипт или ручное исключение висит дольше квартала — считайте его частью архитектуры и оценивайте как рабочую логику продакшна.
  • Проверьте каждый алерт и путь повтора. У команды должен быть один владелец для каждого алерта, один владелец для каждой политики ретраев и одно место, где заложена эта логика.
  • Спросите саппорт, как они решают обычные кейсы. Если они копируют данные между системами, перезапускают джобы вручную или ведут приватный чек‑лист для рутинных проблем, продукт больше зависит от ручного труда, чем команда признаёт.

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

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

Что делать в следующие 30 дней

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

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

Затем примите четыре решения и зафиксируйте их:

  1. Выберите дублирующую систему, которая остаётся. Если два инструмента хранят одни и те же данные клиента или отправляют одни и те же события — одна побеждает, другой получает план выключения.
  2. Назначьте одного владельца для всего потока. Этот человек не обязан делать всю работу, но он должен утверждать изменения и поддерживать карту в актуальном состоянии.
  3. Проверьте каждое оставшееся исключение. Дайте каждому объяснение, срок удаления и ответственного, который его уберёт.
  4. Поставьте одну небольшую задачу на следующий спринт. Примеры: удалить shadow‑базу, убрать ручной экспорт или объединить два пути оповещений.

Держите объём ограниченным. Команда обычно получает больше пользы от исправления одного грязного пути в биллинге, онбординге или саппорте, чем от широкой архитектурной зачистки, которую никто не доделает.

Назначьте даты ревью прямо сейчас. Две недели подходят для активных инцидентов. Тридцать дней — для временных исключений, которые вы ещё можете терпеть. Если дата не назначена, исключение уже стало частью системы.

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

Некоторые команды идут быстрее с внешним обзором, особенно когда внутренние привычки скрывают настоящую причину. Если хотите практическое второе мнение, Oleg Sotnikov предлагает такого рода архитектурные и Fractional CTO обзоры через oleg.is и может помочь решить, что удалить в первую очередь.

Часто задаваемые вопросы

Что такое дрейф архитектуры?

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

Чем дрейф архитектуры отличается от обычного технического долга?

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

Какой первый признак стоит искать?

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

Почему дублирующие системы — такая большая проблема?

Сначала дублирующие системы создают путаницу, потом — инциденты. Команды тестируют по два раза, объясняют данные дважды и исправляют баги дважды. Когда биллинг читает одно место, а саппорт доверяет другому, никто не знает, какое значение должно приводить к реальному бизнес-решению.

Действительно ли единичные исключения так опасны?

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

Как понять, что никто не владеет полным потоком?

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

Что мне следует картировать в первую очередь, если я хочу проверить дрейф?

Выберите один поток, который больше всего страдает при сбое — например, регистрация до оплаты — и нарисуйте все сервисы, базы данных, очереди, скрипты, ручные шаги и людей, которые в это вмешиваются. Быстрая карта обычно быстрее показывает копии, скрытые обходы и пробелы в ответственности, чем большой аудит.

Можно ли исправить дрейф архитектуры без полного переписывания?

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

Как часто нужно проверять временные обходы?

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

Когда имеет смысл привлечь внешнего эксперта?

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