Борьба с техническим долгом и Legacy

Если 10-15 лет назад рассказывали, что такое технический долг, почему он возникает и как может повлиять на дальнейшую разработку, то сейчас начали рассказывать, как с ним бороться. Очевидно, за прошедшие годы многие сильно задолжали. :)

Метафорический образ шаблона Strangler Fig.
Метафорический образ шаблона Strangler Fig.

Судите сами, на прошедшей конференции TechLeadConf 2025 около 30% докладов была посвящена борьбе с техническим долгом и замене Legacy. В конце статьи я привел список из 8 докладов (всего было 27), которые раскрывают эту тему с разных сторон.

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

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

Оценка

С точки зрения бизнеса, техдолг не существует, пока не получит оценку. Бизнесу нужны факты, доказательства, цифры. Только так можно обосновать необходимость устранения долга и "продать" его бизнесу. Иначе говоря, получить одобрение и финансирование таких работ.

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

  • Обывательская надёжность. Как систему видят пользователи. Нужно собрать статистику захода на страницы и на основе этого сделать приоритизацию сценариев.
  • Продуктовая надёжность. Как система выполняет свои задачи. Нужно оценить работоспособность пользовательских сценариев. Для этого следует организовать централизованный реестр с описанием карты пользовательских сценариев (Customer Journey Map, CJM). Каждый сценарий должен иметь описание шагов с указанием используемого API и метрик для оценки Success/Error Rate. Проработку и описание сценариев рекомендуют делать еще на этапе проработки новой функциональности. По итогу не должно остаться методов в API, которые не связаны со сценариями.

Оба способа оценки понятны всем, включая руководство.

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

Из дополнительных тезисов:

  • Если сервис на пути критически важного сценария, он тоже критичен и важен.
  • Инцидент открывается только, если пострадал пользовательский сценарий.

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

Продажа

Мне очень откликнулся доклад Святослава Сычева "Почему мы не даем делать технические задачи и как это помогает бороться с техдолгом?". Предлагается перестроить своё мышление и перестать делить задачи на технические и бизнес. Все задачи формулируются только на языке бизнеса и предметной области. Это налаживает эффективное взаимодействие с заказчиком и избавляет от необходимости постоянно объяснять и доказывать важность и актуальность выполнения работ.

Задачи по устранению техдолга рекомендуется формулировать по шаблону "Situation-Effect-Relevance": что нас беспокоит, какой эффект оказывает, какие последствия возникают. Описание должно быть предельно понятным и включать оценку техдолга. В идеале, если получаемая от реализации польза будет выражена через бизнес-показатели: TTV, ROI и т.п. Подобный подход создает положительный эффект для всех: инженер начинает лучше понимать бизнес, а бизнес сразу видит ценность. Иначе говоря, мы продаём бизнесу задачи и их решения через демонстрацию пользы.

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

Реализация

Продав техдолг, можно приступить к его устранению. В докладе Константина Густова "Миграция с legacy — подходы и практика" выделяются два верхнеуровневых подхода:

  • Эволюционный рефакторинг
  • Постепенная замена (см. шаблон Strangler Fig)

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

До начала разработки нового решения нужно:

  • Назначить владельца продукта. Владельцем должен быть кто-то один.
  • Назначить системного аналитика. Для актуализации существующей документации и формирования реестра пользовательских сценариев (CJM).
  • Создать отдельную команду. Команда должна быть автономной и независимой, иметь собственный backlog. Желательно, чтобы на начальном этапе в команду вошли разработчики Legacy-решения, которые хорошо погружены в прикладной контекст и знают, как устроен бизнес. Возможно, что эти разработчики сразу или позже перейдут в роль аналитиков или консультантов.
  • Определить существующие интеграции. Если Legacy-решение достаточно старое, вполне вероятно, что оно интегрировано в какие-то процессы. Их нужно идентифицировать и задокументировать. Это можно сделать через опрос пользователей или путём сбора метрик использования Legacy API.
  • Определить общую архитектуру. Архитектурный подход должен быть знаком новой команде. Сама по себе миграция — это сложный и дорогостоящий процесс, поэтому нужно выбирать проверенные решения и использовать не более одного-двух незнакомых подходов или технологий. Важно заложить точки дальнейшего роста и эволюции, но удерживать фокус на реальных бизнес-потребностях, а не на идеальной архитектуре.
  • Разработать план замены. План по замене в том числе должен содержать описание не только шагов переключения на новую функциональность, но и шагов отключения старой. Важно помнить, что отключение — это прежде всего про договорённости, а уже затем про удаление кода, освобождение инфраструктуры и актуализацию документации. Также важно определить минимальный объем работ для перехода (MVP).

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

  • Сразу переходить на целевую модель, API и CJM. В большинстве случаев именно это и является причиной замены. Нет смысла повторять старое, иначе его же и получите. Проблему интеграции старого и нового прекрасно решает шаблон Anti-Corruption Layer.
  • Предусмотреть сопряжение интерфейсов. Миграция будет вызывать неудобство у пользователя, поэтому нужно минимизировать эту боль. Необходимо максимально интегрировать пользовательский опыт и не заставлять работать в двух разных системах. Объединение интерфейсов двух систем позволит постепенно заменять старые экранные формы и сценарии.

Из дополнительных тезисов:

  • Не тратить лишнее время на модернизацию Legacy-решений.
  • Весь новый функционал разрабатывать в новом решении.

Прогресс

Как оценивать прогресс устранения техдолга и что именно оценивать? На самом деле ответ на этот вопрос вы должны дать в самом начале, когда аргументировали необходимость устранения техдолга. До начала всех работ нужно определить и разработать критерии оценки. Желательно, чтобы оценка строилась на объективных показателях, получаемых через метрики приложения. Это позволит визуализировать динамику развития.

Дополнительно стоит выделить бизнес-показатели, которые достаточно легко наблюдать:

  • Cost Of Change. Сколько стоит разработка каждой новой функции.
  • Time To Market (TTM). Период от зарождения идеи функциональности до момента её предоставления пользователям.
  • Количество инцидентов. Ключевой вопрос — что считать инцидентом. Например, только то, что затрагивает пользовательские сценарии (см. выше).
  • Mean Time To Recovery (MTTR). Среднее время, необходимое для устранения неисправности или восстановления системы после сбоя.
  • Change Fail Rate (CFR). Процент развертываний, которые привели к сбоям в работе системы и потребовали исправления или отката.
  • Обратная связь от пользователей. Она необходима не только для оценки работы, но и для корректировки вектора развития.

Мотивация

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

Минимальный набор для поддержания здоровой атмосферы в команде:

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

Контроль

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

На что делают ставки сегодня, тезисно:

  • Структурировать, актуализировать и дополнять документацию.
  • Описывать и уточнять пользовательские сценарии до начала их реализации.
  • Наладить процесс технического и архитектурного контроля (TDR/ADR).
  • Проверять систему на соответствие заданному уровню качества.
  • Проверять систему на соответствие бизнес-целям.

Эти действия необходимо выполнять на постоянной основе.

Заключение

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

Я замечаю в этом движении определённую закономерность и системность, и это очень воодушевляет. Интересно посмотреть, как будет дальше развиваться тема автоматизации контроля систем, как архитектурного (CI-конвейер для AaC), так и качественного (SRE-практики), поскольку это формирует базу для здорового роста.

Список докладов

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

  • Продать надежность. Как сделать понятную бизнесу систему приоритизации техдолга и рефакторинга (Павел Лакосников, Авито)
  • Почему мы не даем делать "технические" задачи и как это помогает бороться с техдолгом? (Святослав Сычев, Mindbox)
  • Миграция c legacy — подходы и практика (Константин Густов, М. Девелопер)
  • Заменить двигатель банка на ходу без остановок и аварий (Дмитрий Куянов, Райффайзен Банк)
  • От технического долга к бизнес-целям: рефакторинг архитектуры в реальном кейсе (Марк Быстров, Циан)
  • 12-шаговая программа по управлению техдолгом (Алексей Алешин, Ростелеком ИТ)
  • Legacy — не проблема, а вызов (Александр Гончаров, ГК Юзтех)
  • От монолита к экосистеме контекстов DDD (Сергей Удалов, ecom.tech)

P.s. Если вам интересна данная тематика, присоединяйтесь к моему каналу "Архитектоника в ИТ" в Telegram или здесь. Буду рад поделиться опытом. ;-)

Как вы боритесь с техдолгом? ;-)
Никак, я с ним в симбиозе.
Периодически делаю рефакторинг.
У меня его нет, я пишу чистый код.
Всё сложно, прям как в статье.
Начать дискуссию