Инженерная практика
Собираем вместе: практики — одна петля обратной связи, не чеклист
Команда читает отчёт DORA, выбирает заголовочную практику — «элитные команды деплоят на каждый коммит в trunk» — и насаждает её в понедельник. К среде trunk красный половину дня: нет быстрого набора тестов, что гейтит мержи, так что каждый пуш кладёт сломанную работу поверх сломанной работы. «Фикс» — хотфикс в пятницу под вечер за feature flag. Шесть месяцев спустя есть 340 флагов, ни один не убран, и устаревший выстреливает в проде в Чёрную пятницу. Они внедрили церемонию и пропустили всё, что делало её безопасной.
Практики образуют петлю, не список
Прежние уроки каждый выглядел как самостоятельная дисциплина: TDD и property-тесты, контрактное тестирование, code review, trunk-based development, feature flags, on-call, безвинные постмортемы. Инсайт сеньора в том, что это не семь независимых клеток для галочки. Это одна замкнутая система обратной связи, и порядок важен, потому что каждое звено питает следующее.
Тесты и контрактные проверки производят CI-сигнал, быстрый и достойный доверия настолько, что мержить в trunk много раз в день безопасно. Безопасный частый мерж и есть trunk-based development. Trunk-based development плюс feature flags позволяют деплоить незаконченный или рискованный код тёмным, расцепляя деплой и релиз. Частые мелкие деплои значат, что что бы ни проскользнуло — это крошечный радиус поражения, пойманный on-call. On-call питает инцидент в безвинный постмортем, чьи action items становятся новыми тестами, новыми контрактными утверждениями или новым дефолтом флага — замыкая петлю обратно в начало. Вытащи одно звено, и цепь не просто слабеет; downstream-практика начинает активно вредить тебе.
Отказы на стыках: одна практика без её зависимостей
Отказы не тонки и предсказуемы из графа зависимостей. У каждой практики есть предусловие; пропусти предусловие, и практика инвертируется из актива в обузу.
| Внедрённая практика | Требуемая зависимость | Отказ, если пропущена |
|---|---|---|
| Trunk-based development | Быстрый, достойный доверия CI (тесты + контракты) | Сломанный trunk: все интегрируют поверх красного, сборки стопорятся ежедневно |
| Feature flags | Дисциплина чистки/жизненного цикла (TTL) | Долг флагов: сотни мёртвых тумблеров, комбинаторная матрица тестов, устаревший флаг выстреливает в проде |
| Частые деплои | On-call + быстрый откат/kill флага | Высокая частота деплоев без пути восстановления → высокий MTTR, каждый деплой азартная игра |
| Постмортемы | Владельческие, трекаемые action items | Театр: док, на который никто не действует, та же авария повторяется в следующем квартале |
| Code review | Маленькие батчи (из trunk-based + CI) | PR на 2000 строк получают штамп LGTM; ревью не ловит ничего |
Долг флагов — самый тихо дорогой. Флаг должен быть короткоживущим: Unleash моделирует жизненный цикл initial → pre-live → live → completed → archived, где completed значит «выкат сделан, удаление кода ожидается». Пропусти шаг удаления, и тумблеры накапливаются. Каждый живой флаг удваивает путь через код, так что N флагов подразумевают до 2^N достижимых состояний — матрица тестов, что ты никогда не покроешь целиком. Классическая авария — «release-тумблер», трактуемый как постоянный «permission-тумблер»: его никогда не убирают, он сидит забытым год, а изменение конфига переключает его при пиковом трафике.
Оптимизируй петлю, не церемонию
Ловушка — локальная оптимизация: команда гордо рапортует «мы деплоим 40 раз в день», пока change-fail rate тихо лезет к 30%. DORA существует, чтобы остановить ровно это — она меряет всю петлю четырьмя метриками, что должны двигаться вместе, не одной в изоляции:
- Lead time для изменений — от коммита до работы в проде.
- Частота деплоев — как часто ты шипишь в прод.
- Change failure rate — доля деплоев, что вызывают деградацию сервиса или требуют исправления.
- MTTR / время восстановления после неудачного деплоя — как быстро ты восстанавливаешь сервис после плохого изменения.
Разброс отчёта DORA 2024 между элитными и низкими исполнителями — это аргумент: элиты деплоят примерно в 182 раза чаще, с lead time примерно в 127 раз быстрее, восстанавливаются после инцидентов примерно в 2293 раза быстрее и имеют change-fail rate примерно в 8 раз ниже. Заметь, что это не в противоречии — скорость и стабильность растут вместе, потому что петля, что делает тебя быстрым (маленькие батчи, сильный CI, флаги, быстрый откат), — та же петля, что делает тебя безопасным. Отчёт 2024 даже увидел «высокий» кластер, чей CFR был хуже, чем у более медленного-но-осторожного «среднего» кластера — доказательство, что погоня за одной частотой деплоев, без метрики стабильности, что её правит, регрессирует систему.
Почему это работает
Что скорость и стабильность — трейдофф, это самый упрямый миф тут. Данные говорят обратное: те же способности, что сжимают lead time — крошечные батчи, достойные доверия автотесты, расцепление деплой/релиз через флаги — также сжимают change-fail rate и MTTR, потому что маленькие изменения легче ревьюить, легче осмыслить и тривиально откатить. Команда, что быстра и нестабильна, не переоптимизировала скорость; она пропустила зависимости (CI, флаги, восстановление), что делают скорость безопасной.
Чтение петли в инциденте
Проведи реальный инцидент через петлю, и зависимости становятся конкретными. Плохое изменение шипится. Поскольку батчи маленькие (trunk-based + CI), изменение — один PR, не пятьдесят, так что on-call инженер бисектит до него за минуты, не часы — это низкий MTTR. Поскольку рискованный путь был за флагом, восстановление — выключение флага, не откат кода и редеплой. Безвинный постмортем спрашивает не «кто запушил», а «какое звено его пропустило»: пробел CI был недостающим контрактным тестом? Тогда action item — контрактное утверждение. Была это непротестированная комбинация флагов? Тогда action item — политика чистки флагов плюс дефолт. Каждый ответ питает конкретную upstream-практику. Постмортем без владельческого action item — единственный стык, что тихо ломает всю петлю, потому что это звено, что превращает инцидент в постоянное улучшение.
Руководство хочет «элитные числа DORA за один квартал». Команда сейчас деплоит еженедельно с медленным флейки-набором тестов и без флагов. Какова последовательность сеньора?
Команда внедряет trunk-based development, но всё ещё имеет 25-минутный, часто флейки набор тестов. Каков предсказуемый исход?
Твоя команда деплоит 40 раз/день и хвастается этим, но change-fail rate 28%, а MTTR ползёт вверх. Что DORA говорит ты сделал не так?
Расставь петлю обратной связи так, чтобы каждое звено включало следующее:
- 1 Тесты + контрактные проверки дают быстрый, достойный доверия CI-сигнал
- 2 Достойный доверия CI делает мерж в trunk много раз в день безопасным (trunk-based)
- 3 Trunk-based + feature flags расцепляют деплой и релиз; маленькие рискованные изменения шипятся тёмными
- 4 Мелкие частые деплои значат, что проскользнувшее имеет крошечный радиус поражения, пойманный on-call
- 5 Безвинный постмортем превращает инцидент в action items: новые тесты, контракты, дефолты флагов — замыкая петлю
- 01Объясни, почему насаждение trunk-based development до починки CI предсказуемо бьёт по тебе, и какова правильная последовательность.
- 02Почему DORA настаивает на четырёх метриках, двигающихся вместе, и что идёт не так, когда команда оптимизирует одну частоту деплоев?
Семь практик этого трека — не чеклист независимых ритуалов, а одна замкнутая петля обратной связи, и порядок несущий. Тесты и контрактные проверки производят CI-сигнал, достойный доверия настолько, что мерж в trunk много раз в день безопасен; trunk-based development плюс feature flags расцепляют деплой и релиз; мелкие частые деплои держат радиус поражения любого побега крошечным, где on-call его ловит; а безвинный постмортем с владельческими action items превращает тот инцидент в новые тесты, контракты и дефолты флагов, замыкая петлю. Вытащи зависимость, и downstream-практика инвертируется: trunk-based без CI даёт сломанный trunk, флаги без чистки дают долг флагов и устаревший тумблер, выстреливающий в проде, частые деплои без пути восстановления дают высокий MTTR, постмортемы без action items дают повторные аварии. Финальная дисциплина — перестать оптимизировать отдельные церемонии и вместо этого оптимизировать всю петлю, правимую четырьмя метриками DORA вместе — потому что данные однозначны, что скорость и стабильность растут как одно, когда петля цела, и регрессируют вместе, когда звено отсутствует.