Развертывание — это когда код поступает в производство. Релиз — это когда кто-то действительно может его использовать. Смешение этих двух моментов — один из самых быстрых способов превратить каждое развертывание в немного напряженный момент.
feature flag служит для того, чтобы создать пространство между этими двумя моментами. Вы можете развернуть сегодня, запустить завтра для внутренней команды, затем для пилотного клиента, затем для 10% пользователей. Если что-то пойдет не так, выключите флаг. Вам не обязательно выполнять откат всей версии.
Флаг — это не просто if
Технически это часто if. В культурном отношении это нечто большее.
if (await flags.isEnabled('checkout.v2.enabled', context)) { return newCheckout(input); } return oldCheckout(input);
Этот маленький if может означать постепенное развертывание, эксперимент, миграцию, разрешение на предпринимательство или kill switch в эксплуатацию. Проблема в том, что если вы плохо с этим справитесь, это также может стать техническим долгом, который останется в коде на два года.
Откуда здесь OpenFeature
OpenFeature — открытая спецификация для оценки feature flag с общим API. Идея проста: код вашего приложения не должен напрямую зависеть от поставщика или внутренней системы, которую вы используете для флагов.
Приложение спрашивает:
const enabled = await client.getBooleanValue('checkout.v2.enabled', false, { targetingKey: user.id, plan: user.plan, country: user.country, });
Поставщик решает, откуда берутся правила: SaaS, файл, внутренний сервис, flagd, конфигурация GitOps. Если однажды вы измените серверную часть пометки функций, приложение не придется переписывать повсюду.
Такое разделение кажется архитектурной деталью, но оно ощущается по мере роста проекта.
Контекст – это половина дела
Флаг включения или выключения для всех полезен, но ограничен. Прогрессивная доставка живет в контексте:
- внутренний или внешний пользователь;
- бесплатный или корпоративный план;
- деревня;
- организация;
- версия приложения;
- стабильный процент трафика.
Важным ключом является targetingKey: он должен быть стабильным. Если он меняется при каждом запросе, пользователь может оказаться один раз в варианте А, один раз в варианте Б. Для эксперимента это ужасно, для кассы — катастрофично.
Разумное внедрение
Мне нравится такой поток:
- развернуть со снятым флагом;
- зажигание для разработчиков и QA;
- включение пилотного заказчика или арендатора;
- 5% внедрение;
- внедрение на уровне 25%;
- 100% внедрение;
- удаление старого кода и флага.
Часто забываемый пункт — последний. Временный флаг должен иметь дату смерти. Если она останется навсегда, каждому будущему рефакторингу придется спрашивать: «А полезна ли еще эта ветка?».
Kill switch: сначала подготовь их
kill switch — это флаг, который спасает вас, когда внешняя зависимость начинает мешать вам, задание потребляет слишком много ресурсов или новая логика выдает странные ошибки.
Хорошая kill switch должна быть:
- легко найти;
- задокументировано в Runbook;
- проверялся время от времени;
- наблюдаемый при активации;
- независимый, насколько это возможно, от той части, которая может сломаться.
Самое страшное – обнаружить во время аварии, что флаг существует, но никто не знает, работает ли он еще.
Наблюдаемость или непрогрессивная доставка
Включить фичу на 10% без учета метрик — это просто оптимизм с несколькими шагами.
Каждое внедрение должно отвечать на простые вопросы:
- увеличились ли ошибки?
- изменилась ли задержка?
- завершают ли пользователи поток?
- есть ли еще билеты или повторы?
- влияет ли вариант только на один сегмент?
OpenFeature поддерживает перехваты для оценки флагов. Они полезны для регистрации ошибок, добавления показателей или привязки рейтинга к trace.
Именование и право собственности
Имена имеют значение. new_ui ничего не говорит. checkout.v2.enabled говорит гораздо больше.
Для каждого флага я бы отметил как минимум:
- имя;
- описание;
- владелец;
- безопасный дефолт;
- причина, почему оно существует;
- дата или условия удаления.
Флаг, не имеющий владельца, почти всегда является флагом, который никто не снимет.
Где их оценивать
Фронтенд, бэкенд или периферия? Зависит от.
Если флажок установлен для макета, копирования или адаптации, с интерфейсом все в порядке. Если речь идет о разрешениях, выставлении счетов, лимитах или конфиденциальных данных, это должно быть на серверной стороне. Если речь идет о маршрутизации или экспериментах с высоким трафиком, периферия может иметь смысл.
Простое правило: интерфейс может улучшить взаимодействие с пользователем, но он не должен быть единственным барьером безопасности.
Заключение
Хорошо сделанные feature flag меняют отношения с производством. Они не устраняют риск, но делают его меньшим и более управляемым. Можно выпускать кусочками, наблюдать, останавливаться, возвращаться, учиться.
OpenFeature добавляет чистую основу: общий API, взаимозаменяемые поставщики и более удобный способ развития системы. Но дисциплина остается за вами: безопасные настройки по умолчанию, четкие имена, метрики, владельцы и чистота.
Лучший флаг — это тот, который помогает вам спокойно отпустить, а затем исчезает, когда он больше не нужен.