Содержание

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

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

Какие задачи решают feature flags?

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

Что дают флаги:

  • постепенный выпуск — функция включается для 1%, 10%, 50% пользователей с наблюдением за метриками;
  • аварийное выключение — проблемную функцию отключают без отката и нового релиза;
  • короткие ветки — незавершённая работа живёт в основной ветке под выключенным флагом;
  • A/B-тесты — разным группам показывают разные варианты и сравнивают результат;
  • доступ по тарифу — функции включаются для определённых клиентов или планов подписки.

Какие бывают типы флагов?

Флаги различаются по сроку жизни и по тому, кто ими управляет. Временные флаги для выпуска должны жить недели, а постоянные — например, доступ по тарифу — остаются в продукте надолго.

Тип Зачем Срок жизни Кто управляет
Релизный Постепенно выпустить функцию Дни–недели Разработчики
Экспериментальный A/B-тест Недели Продукт
Операционный Аварийно отключить тяжёлую функцию Постоянно Дежурные инженеры
Разрешение Доступ по тарифу или клиенту Постоянно Продукт и продажи

Зелёный выключатель с двумя тумблерами Фото: Unsplash

Как устроить флаги технически?

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

if (Feature::for($user)->active('new-checkout')) {
    return $this->newCheckout($cart);
}

return $this->legacyCheckout($cart);

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

Где проверять флаги:

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

Как флаги помогают выпускать релизы безопаснее?

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

Типичный сценарий выпуска:

  1. Код выкатывается с выключенным флагом.
  2. Функцию включают для сотрудников и тестировщиков.
  3. Затем — для 5–10% пользователей с наблюдением за ошибками и бизнес-метриками.
  4. Если всё в порядке, долю постепенно увеличивают до 100%.
  5. Через несколько дней флаг и старый код удаляют.

Подробнее о безопасных релизах — в статьях релизы без простоя и CI/CD на GitHub Actions, а о метриках — в материале мониторинг и логирование.

Как не превратить флаги в технический долг?

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

Правила гигиены:

  • при создании флага сразу заводите задачу на его удаление;
  • ограничьте количество одновременно живых релизных флагов;
  • не вкладывайте флаги друг в друга;
  • регулярно смотрите список флагов, которые включены на 100% больше месяца;
  • называйте флаги понятно: что включает и с какой даты.

О том, как управлять накопленными упрощениями, мы писали в статье технический долг.

Коротко

  • Флаги отделяют выкладку кода от включения функции для пользователей.
  • Они дают постепенный выпуск, аварийное выключение, A/B-тесты и доступ по тарифу.
  • Значения флагов кешируются, а для процентов используется хеш пользователя.
  • Выпуск идёт по шагам: сотрудники, небольшая доля пользователей, все.
  • У каждого временного флага есть владелец и срок удаления.

Частые вопросы

  • Нужен ли платный сервис для флагов?

    Не обязательно. Небольшой команде хватает флагов в базе данных или конфигурации с простой админкой. Платные сервисы оправданы, когда флагов много, нужны A/B-тесты, аудит изменений и управление продуктовой командой без разработчиков.

  • Замедляют ли флаги приложение?

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

  • Как тестировать код с флагами?

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