Mid Авторский

Feature Flags

Деплой и релиз: разные вещи. Как флаги меняют процесс доставки

Первоисточник

Feature Toggles (aka Feature Flags)

Pete Hodgson, 2017

Деплой и релиз: два разных события

На ранних этапах внедрения CI/CD слова «задеплоить» и «зарелизить» кажутся синонимами: код попадает на продакшен-сервер, пользователи видят новую функциональность, готово. Но рано или поздно возникает ситуация, которая заставляет пересмотреть это тождество: команда доделала фичу, задеплоила, и маркетинг попросил подождать с релизом до следующего вторника, потому что у них была запланирована PR-кампания. И вот все сидят на заведённой бомбе: код в продакшене, но пользователям его показывать нельзя, и если кто-то увидит незаанонсированный функционал, будет скандал.

Feature flags решают эту проблему: деплой и релиз становятся двумя независимыми операциями. Деплой: код попадает на серверы. Релиз: пользователи получают доступ к новому функционалу. Между ними может пройти минута, день или неделя, и разработчикам не нужно держать отдельную ветку, замораживать мерж или координировать timing с десятком команд.

Как устроен feature flag

В минимальном виде feature flag это условие в коде:

if (featureEnabled("new-checkout")) {
  renderNewCheckout();
} else {
  renderOldCheckout();
}

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

Pete Hodgson в статье на сайте Martin Fowler выделяет несколько категорий флагов, и это разделение критически важно, потому что разные категории требуют разного управления.

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

Experiment toggles управляют A/B-тестами. Живут столько, сколько идёт эксперимент (обычно недели), и привязаны к конкретным когортам пользователей.

Ops toggles дают команде эксплуатации возможность отключить тяжёлую функциональность под нагрузкой. Могут жить долго и работать как circuit breaker.

Permission toggles управляют доступом к функциям для разных категорий пользователей (free vs premium, бета-тестеры). Живут столько, сколько существует разделение.

Progressive rollout

Одна из сильных возможностей feature flags: постепенное раскатывание. Вместо того чтобы включить фичу для всех 100% пользователей и молиться, что ничего не сломается, вы начинаете с 1%, смотрите на метрики (error rate, latency, конверсия), и если всё в порядке, увеличиваете до 5%, потом 10%, потом 50%, потом 100%.

Unleash поддерживает стратегии постепенного раскатывания из коробки: вы задаёте процент пользователей, выбираете стратегию (gradual rollout, user ID, IP), и система направляет трафик по заданным правилам. В связке с Grafana и Prometheus вы видите метрики в реальном времени и принимаете решение об увеличении процента или откате. GrowthBook пошёл ещё дальше и встроил статистический анализ A/B-экспериментов в сам инструмент, так что вы получаете не просто графики, а оценку статистической значимости результатов.

Это меняет отношение к риску. Деплой перестаёт быть бинарным событием «всё или ничего» и превращается в управляемый процесс с возможностью мгновенного отката. Откатить feature flag: переключатель в интерфейсе или API-запрос, который срабатывает за секунды. Откатить деплой: пайплайн, который занимает минуты или часы.

Инструменты

Рынок feature flag-платформ зрелый. Для команд, которым важен контроль над данными и инфраструктурой, лучший выбор сегодня: open-source решения с self-hosting.

Unleash (GitHub). Главная рекомендация. Open-source, self-hosted, данные остаются на ваших серверах. Поддерживает targeting по пользователям и сегментам, стратегии постепенного раскатывания, A/B-тесты, audit log. SDK для 15+ языков. Интеграция с Grafana и Prometheus через встроенные метрики. Есть платная managed-версия Unleash Edge для тех, кто не хочет поднимать инфраструктуру сам.

Flagsmith (GitHub). Open-source, self-hosted. Включает remote config: не только boolean-флаги, но и значения (строки, числа, JSON). Хороший вариант, если вы хотите управлять feature flags и конфигурацией из одного места. Есть REST API и вебхуки для интеграции с Grafana OnCall для алертинга.

GrowthBook (GitHub). Open-source платформа, которая объединяет feature flags и A/B-эксперименты. Встроенный статистический движок анализирует результаты экспериментов и показывает значимость. Подключается к вашему data warehouse (ClickHouse, Postgres, BigQuery) для анализа метрик.

OpenFeature (GitHub). Открытый стандарт от CNCF, который задаёт единый API для работы с feature flags. Позволяет переключаться между провайдерами (Flagsmith, Unleash, GrowthBook) без переписывания кода. SDK для Go, Java, .NET, JavaScript, Python и других языков. Если вы закладываете архитектуру на вырост, начните с OpenFeature API и подключите любой провайдер.

LaunchDarkly остаётся лидером enterprise-рынка с самым широким набором интеграций и SDK для 25+ языков. Но это SaaS с серверами за пределами РФ и ценником от $10/месяц за разработчика, что делает его менее подходящим для команд с требованиями к локализации данных.

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

Техдолг от флагов

Pete Hodgson формулирует самую частую проблему с feature flags так: «flag debt». Стейловые флаги засоряют кодовую базу условиями и мёртвым кодом. Вы создали флаг для релиза фичи полгода назад, фича давно работает для всех пользователей, но условие в коде осталось, старая ветка кода осталась, и никто не может сказать, безопасно ли её удалить, потому что автор уволился в прошлом квартале.

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

Практики для борьбы с flag debt:

Expiration date. При создании флага указывайте дату, после которой его нужно удалить. Если дата прошла, а флаг живой, CI кидает warning или блокирует сборку.

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

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

Правило при создании. Pete Hodgson рекомендует при каждом создании release toggle добавлять в бэклог задачу на его удаление. Флаг и задача на его удаление: неразрывная пара.

Рекомендации

Начните с release toggles. Это самый полезный и самый безопасный тип флагов. Вы получите возможность деплоить незавершённый код, разделить деплой и релиз, и освоите саму практику работы с флагами.

Выберите инструмент по размеру: для команды из 5 человек хватит переменных окружения и простого конфига. Для команды из 50 нужна платформа с targeting, audit log и API. Не переусложняйте на старте, но используйте OpenFeature API с первого дня, чтобы потом не переписывать код при смене провайдера.

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