Перейти к основному содержимому

Feature flags — постепенный выкат и kill switch

Разработчику Архитектору

Feature flags — что это

Feature flag (feature toggle) — переключатель поведения приложения без полного redeploy (или с минимальным изменением конфигурации). Код новой фичи уже в main и на prod, но выключен для пользователей, пока команда не включит флаг. Связь с DoD и релизом:

Проблема без флаговРешение с флагами
Big bang — все сразу на новом checkoutGradual rollout 5% → 50% → 100%
Баг на prod — hotfix redeploy 40 минKill switch — off за секунды
Long-lived branch месяцамиКод в main за флагом off
A/B два UIExperiment flag по сегменту

YAGNI · легаси / модернизация.

Флаг — не костыль навсегда

У каждого release-флага должна быть дата снятия: после 100% rollout удалить старый путь и if-ветку. Иначе — flag debt и if-hell.


Gradual rollout

Gradual rollout (постепенный выкат) — включение фичи для растущей доли пользователей или серверов:

  1. Internal — только сотрудники (dogfood).
  2. 5% — canary, смотрим метрики и ошибки.
  3. 25% → 50% — если SLO в норме.
  4. 100% — полный rollout, план удаления старого кода.

Метрики: error rate, latency p95, conversion (аналитика). Rollback на предыдущий % — без отката бинарника.


Kill switch

Kill switch — оперативное выключение фичи при инциденте:

  • checkout падает с 500 — flag off, пользователи на старый flow;
  • тяжёлый отчёт кладёт БД — ops-flag off;
  • интеграция партнёра недоступна — отключить новый канал.

Runbook P1 часто начинается: "1) Kill switch feature_x in LaunchDarkly. 2) Подтвердить метрики. 3) RCA."

Kill switch должен быть:

  • быстрым (секунды, не redeploy);
  • документированным в wiki и release notes;
  • протестированным на stage ("fire drill").
Kill switch не заменяет мониторинг

Флаг спасает пользователей, пока вы чините код. Без алертов вы узнаете о проблеме поздно — включите метрики до 5% rollout.


Типы feature flags

ТипПримерСрок жизни
ReleaseНовый checkoutУдалить после 100%
OpsТяжёлый nightly reportДолго, пока не оптимизируют
PermissionBeta для enterprise-клиентовДо GA или сегмента
ExperimentДва варианта CTAДо решения PO по A/B
Kill switchНовая payment providerПока риск интеграции

Не смешивайте типы в одном флаге flag1 — разные политики rollout и владельцы.


Именование и lifecycle

  1. Именованиеproduct.area.feature, например shop.checkout.one_tap, не newCheckout.
  2. Owner — PO или dev в wiki-реестре флагов.
  3. Created / target removal — даты в тикете.
  4. Default — prod off для release flags до PO approval.
  5. Аудит — кто включил 100% в prod (change).

Реализация в коде

Минимальный паттерн (псевдокод):

if (featureFlags.isEnabled('shop.checkout.one_tap', user)) {
return renderOneTapCheckout(cart);
}
return renderLegacyCheckout(cart);

Правила:

  • Не ветвить всё — if-hell; изолируйте стратегию (Strategy / отдельный модуль).
  • Fallback при недоступности сервиса флагов — безопасный default (обычно off).
  • Не прятать security checks за флагом без review.
  • Удалять мертвую ветку после rollout — пункт DoD.

LaunchDarkly — пример платформы

LaunchDarkly (LD) — коммерческая платформа feature flags с UI, targeting, audit log, интеграциями. Open-source альтернативы: Unleash, Flagsmith, GrowthBook (experiments).

Основные концепции LD

КонцепцияОписание
Project / Environmentdev, stage, prod — разные ключи SDK
FlagBoolean, string, JSON
TargetingПо user key, segment, geo, % rollout
Variationtrue/false или multivariate
Audit logКто изменил правило

Пример сценария ShopFlow

  1. Dev создаёт flag checkout_one_tapoff в prod.
  2. Deploy 2.14.0 — код на prod, флаг off — пользователи на legacy.
  3. PO включает true для segment employees — dogfood.
  4. Rollout 5% anonymous + мониторинг dashboard.
  5. 50% → 100% за неделю.
  6. Тикет: удалить legacy checkout + flag в 2.16.0.

SDK (упрощённо)

import * as LD from '@launchdarkly/node-server-sdk';

const client = LD.init(process.env.LD_SDK_KEY);
await client.waitForInitialization();

const context = { kind: 'user', key: user.id, email: user.email };
const showOneTap = await client.variation('checkout_one_tap', context, false);

Кontext attributes — для targeting (страна, plan). Не кладите секреты в context.

LaunchDarkly и DoD

DoD крупной фичи может включать:

  • Flag создан в LD prod, default off
  • Runbook kill switch в wiki
  • Dashboard/alerts подключены
  • Release notes упоминают флаг и gradual plan
  • Stage fire drill: off → пользователь на legacy ≤ 1 мин

Другие способы хранения флагов

ПодходКогда
LaunchDarkly / UnleashProd, gradual, audit
ConfigMap / K8sOps toggles, infra
Env var % rolloutMVP, прототип (осторожно)
DB tableПростой admin UI, нужен audit

Для гос/регуляторного контура — трассируемость изменений (change), on-prem Unleash.


Feature flags и mobile

Store release медленный — флаги критичны:

  • билд в App Store с флагом off;
  • включение без новой submission (remote config / LD mobile SDK);
  • kill switch без ожидания review Apple/Google.

DoD mobile: см. глава 2.


A/B и experiments

Experiment flag — две variations, метрика conversion. PO решает победителя; проигравший код удаляют. Не оставлять experiment 6 месяцев "на всякий случай".

Продуктовая аналитика.


Feature flags и инциденты

Связь с incident management: on-call должен иметь доступ к LD/console и ссылку в runbook.


DoR, DoD и флаги

ФазаФлаг
DoRPO описал rollout plan?
РазработкаКод за флагом, default off
DoDFlag in prod, runbook, metrics
Post-100%Тикет на удаление flag + legacy

Антиpatterns

АнтиpatternПоследствие
200 stale flagsif-hell, страх трогать код
Флаг без ownerНикто не выключает experiment
Default on в prodBig bang через заднюю дверь
Нет fallback при падении LDOutage флагов = outage продукта
Флаг для каждой мелочиOverhead > value

Реестр флагов (wiki)

FlagTypeOwnerDefault prodTarget removalRunbook
shop.checkout.one_tapRelease@pooff2026-08-01RB-142

Review реестра раз в спринт — 5 минут на retro.


Связь с release notes

В release notes:

## Новое
- Быстрая оплата — поэтапное включение (flag `checkout_one_tap`).

## Для администраторов
- Kill switch: LaunchDarkly → checkout_one_tap → off
- Текущий rollout: 25% (обновлено 2026-06-18)

Support не говорит "у нас баг" — "фича ещё не на вашем сегменте".


LaunchDarkly: targeting и сегменты

МеханизмПример использования
User keyBeta для user-12345
Custom attr planenterprise и free — разные правила
GeoRU rollout отдельно от EU
Percentage rollout5% anonymous
Rules orderStaff → enterprise → %

Правило: staff always on для dogfood — отдельное правило выше percentage.

Пример правил (концептуально)

  1. IF segment employees → true
  2. ELSE IF attribute country = DE AND plan = premium → 50% true
  3. ELSE → false

Тестируйте rules на stage environment LD перед prod.


Unleash и open source (кратко)

Unleash — self-hosted альтернатива:

Trade-off: свой ops или SaaS LD.


Тестирование feature flags

ТестГде
Flag off — legacy pathUnit + E2E
Flag on — new pathUnit + E2E
Flag service down — fallbackIntegration
Kill switch drillStage manual + runbook

DoD: оба пути зелёные в CI перед prod deploy.


Flag debt — управление

Еженедельно bot или тимлид:

  • флаги старше 90 дней при 100% rollout → тикет "remove flag X";
  • experiment без решения PO > 30 дней → эскалация;
  • count if (flag) в repo — trend на retro.

YAGNI · легаси.


Кейс: инцидент и kill switch (пошагово)

  1. 14:02 UTC — alert error rate checkout 8%.
  2. 14:04 — on-call открывает LD, checkout_one_tapoff.
  3. 14:06 — error rate 0.3%, legacy path работает.
  4. 14:30 — RCA начат, тикет INC-501.
  5. 16:00 — fix в main, deploy, flag on 5% internal.
  6. +48h — gradual resume по плану.
  7. Release notes hotfix + known issue closed.

Связь incident · change.


Feature flags и DoD — полная матрица

ЭтапRelease flagOps flagExperiment
DoRRollout plan?N/AHypothesis + metric
CodeBoth paths testedToggle documentedVariations
DoDOff in prod, runbookAlert linkedAnalytics events
PostRemove by dateReview quarterlyPick winner, delete

Стоимость и лицензии

LaunchDarkly — per seat / MAU; для старта:

  • оцените MAU и environments;
  • dev/stage/prod — отдельные SDK keys;
  • не шарить prod key в frontend repo — client-side ID только для safe flags.

Чекlist перед первым 5% rollout

  • Dashboard error rate и latency на legacy и new path
  • Kill switch tested on stage ≤ 60 сек до legacy
  • On-call имеет доступ LD и runbook URL
  • Support briefed (release notes)
  • PO sign-off на процент и сегмент
  • Rollback не требует DB restore (или runbook DB)

Итоги раздела

Feature flags — мост между DoD и безопасным prod: gradual rollout снижает риск, kill switch сокращает MTTR. LaunchDarkly и аналоги дают targeting и audit; MVP может начать с Unleash или env, но kill switch и runbook нужны до 5% пользователей.

Итоги раздела · Чек-лист