Feature Flags e rilascio
Feature Flag (FF) è una condizione guidata che attiva/disattiva il comportamento del sistema senza rilasciare il codice. Le bandiere consentono di espellere i fili in modo sicuro, targare gruppi di utenti/mercati/tenenti, disattivare rapidamente i componenti problematici, eseguire esperimenti e configurare i parametri in un rate.
Obiettivi chiave:- Riduce i blast radius nelle release.
- Separare l'installazione e l'attivazione.
- Consente di gestire le modifiche in modo trasparente con l'audio, il SLO e il reimpostato in un clic.
1) Tipi di bandiere e quando applicarli
Release flags - Inserimento graduale di un nuovo filetto (dark canary ramp-up (100%).
Ops/kill-switch - Disattivazione istantanea delle dipendenze (provider, sottosistema, calcoli pesanti).
Experience (A/B, multi-variant) - Divide il traffico in opzioni (weights, sticky bucketing).
Permision/Entitlement - Accesso ai file per ruoli/piani/giurisdizioni.
Remote Config - Parametri di comportamento (soglia, timeout, formula) del flag/config.
Migration flags - Alterna diagrammi/percorsi dati (spostamento a nuovo indice/database/endpoint).
Anti-Pattern: la stessa bandiera «su tutto» - fraziona su Fiju, maglione e parametri.
2) Modello dati flag (minimo)
yaml flag:
key: "catalog. new_ranker"
type: "release" # release ops kill experiment permission config migration description: "New Directory Ranking"
owner: "search-team@company"
created_at: "2025-10-01T10:00:00Z"
ttl: "2026-01-31" # delete deadline after 100% enable rules:
- when:
tenant_id: ["brand_eu","brand_latam"]
region: ["EE","BR"]
user_pct: 10 # progressive percentage then: "on"
- when:
kyc_tier: ["unverified"]
then: "off"
variants: # for experiments
- name: "control"; weight: 50
- name: "v1"; weight: 30
- name: "v2"; weight: 20 payload:
v1:
boost_freshness: 0. 3 boost_jackpot: 0. 2 v2:
boost_freshness: 0. 2 boost_jackpot: 0. 4 prerequisites: # dependent flags/schema versions
- key: "catalog. index_v2_ready"
must_be: "on"
audit:
require_ticket: true change_window: "09:00-19:00 Europe/Kyiv"
safeguards:
max_rollout_pct: 50 # stop threshold auto_rollback_on:
p95_ms: ">200"
error_rate: ">2%"
3) Valutazione e targeting (evaluation)
Ключи таргетинга: `tenant_id, region/licence, currency, channel, locale, role, plan, device, user_id, cohort, kyc_tier, experiment_bucket`.
Ordine di valutazione: prerequisites-deny-regole per il default.
Sticky bucketing - Per gli esperimenti, accetta un ID stabile (ad esempio, «hash (user _ id, flag _ key)») in modo che l'utente riceva sempre una sola opzione.
ts result = evaluate(flag, context) // pure function if (!prereqs_ok(result)) return OFF if (deny_match(result, ctx)) return OFF if (allow_match(result, ctx)) return resolve_variant_or_on(result, ctx)
return flag. default
4) Distribuzione e architettura FF
Opzioni:- Server-side SDK (raccomandato): origini di verità e cache nel backend unificazione logica.
- Edge/CDN evaluation: targeting rapido sul perimetro (senza PII/segreti).
- Client-side SDK: quando è necessaria la personalizzazione dell'UI, ma solo con un contesto minimo e senza regole sensibili.
- Config-as-Code - Memorizzazione dei flag nel repository, convalida CI, rollout tramite CD.
- Startup bootstrap + streaming updates (SSE/gRPC) + fallback all'ultimo snack.
- SLA «freshness» delle bandiere: p95 ≤ 5.
5) Strategie di rilascio
5. 1 Dark Launch
Fic attivato ma invisibile all'utente; raccogliendo metriche e errori.
5. 2 Canary
Includiamo 1-5% del traffico in una giurisdizione/tenante; monitor p95/p99, errori, conversione.
Stop condizioni sono i trigger di soglia dell'autoscafo per metriche.
5. 3 Progressive Rollout
10% per 25% per 50% per 100% per la convalida manuale/automatica.
5. 4 Shadow / Mirroring
Duplicare le query in un nuovo percorso (senza effetto apparente) e confrontare i risultati/latitanza.
5. 5 Blue/Green + FF
Distribuire due versioni; il flag guida il traffico e alterna le dipendenze in base ai segmenti.
6) Dipendenze e consistenza cross-servizio
Usate prerequisites e i «flag health» pronti: indice costruito e migrazione completata.
Coordinazione attraverso eventi: 'FlagChanged (flag _ key, scope, new _ state)'.
1. attivare il percorso read 2) controllare le metriche (3) attivare write/side-effects.
- Contratti di servizio: default deve essere sicuro (fail-safe OFF).
7) Osservabilità e SLO
Metriche per flag/variante/segmento:- `flag_eval_p95_ms`, `errors_rate`, `config_freshness_ms`.
- Le metriche aziendali sono: «ctr», «conversion», «ARPU», «retention», «guardrail» (ad esempio, incidenti RG).
- Soglie SLO automatiche per autoscafo.
Logi/tracking: aggiungi «flag _ key», «variant», «definition _ source» (server/edge/client), «text _ hash».
Le scale rollout con le soglie, gli errori di heatmap per i segmenti.
8) Sicurezza e compliance
Minimizzazione PII nel contesto.
RLS/ACL: chi può cambiare le bandiere (per dominio/mercato).
Finestre orarie di modifica (change windows) e doppia conferma per i flag sensibili.
Controllo immutabile: chi/quando/cosa/perché (ticket/incident link).
Giurisdizione: le bandiere non devono superare i divieti regolatori (ad esempio, includere un gioco in un paese proibito).
9) Controllo delle bandiere «a lunga vita»
Ogni flag ha una TTL/data di rimozione.
Dopo aver attivato il 100% - Crea task per rimuovere i rami di codice, altrimenti il flag-debito cresce.
Contrassegnare le bandiere comè migration '/' one-time ', separarle dalle costanti «persistence/config».
10) Esempio di contratto API/SDK
Evaluation API (server-side)
http
POST /v1/flags/evaluate
Headers: X-Tenant: brand_eu
Body: { "keys":["catalog. new_ranker","rgs. killswitch"], "context": { "user_id":"u42", "region":"EE" } }
→ 200
{
"catalog. new_ranker": { "on": true, "variant":"v1", "as_of":"2025-10-31T12:10:02Z" },
"rgs. killswitch": { "on": false, "variant":null, "as_of":"2025-10-31T12:10:02Z" }
}
Client SDK (кэш, fallback)
ts const ff = await sdk. getSnapshot() // bootstrap const on = ff. isOn("catalog. new_ranker", ctx)
const payload = ff. payload("catalog. new_ranker", "v1")
11) Interazione con altri tracciati
Rate limits/quote - I flag possono abbassare RPS/includere il trottling durante l'incidente.
Circuito breaker/degradation: kill-switchi disattivano i percorsi pesanti e includono il degrado.
Directory/Personalizzazione: le bandiere cambiano peso/regole di classificazione (tramite Remote Config).
Migrazioni database: le bandiere tradurranno progressivamente le letture/registrazioni in un nuovo schema (read-replica-dual-write-write-primary).
12) Playbooks (runbooks)
1. Incidente dopo l'attivazione del 25%
L'autoscafo ha suonato la bandiera OFF per tutti i/i segmenti, il ticket in on-call, la raccolta di stati, RCA.
Attivare temporaneamente il degrado/vecchio ramo tramite migration flag.
2. Altezza p95 per catalogo
Soglia «p95 _ ms> 200» - Autoscafo; Fissa le righe con "flag _ key = catalog. new_ranker`.
Attiva i segnali di classificazione semplificati (payload config).
3. Discrepanza di giurisdizione
Il flag permision ha aperto erroneamente il gioco in «NL» - OFF + Post-Fatto controllo, aggiunta di una regola guard «region deny».
4. Dispersione in A/B
Arresta l'esperimento, esegue analisi CUPED/stratified, rilascia i pesi aggiornati.
13) Test
Unità: valutazione determinata delle regole/priorità/prefigurazioni.
Contract: schema delle bandiere (JSON/YAML), validatori, controllo CI prima del murge.
Property-based: «deny> allow», «not specific wins», bucketing stabile.
Replay: riproduce i contesti reali sulla nuova configurazione.
E2E: script canarini (step-up/step-down), controllo dell'autolavaggio e controllo degli eventi.
Chaos: strapiombo, antiquato, rinnovamento massiccio delle bandiere.
14) Errori tipici
Logica segreta nelle bandiere client (fughe/scambi).
L'assenza della TTL → il cimitero delle bandiere nel codice.
Le bandiere «universali» non possono essere localizzate senza segmentazione.
Niente guardrails/auto - incidenti manuali.
Dipendenze incompatibili tra le bandiere dei cicli/rassincrone.
Valuta i flag in ogni query senza la cache di un picco di latenza.
Nessun controllo/finestra di modifica - Rischi di compilazione.
15) Foglio di assegno prima della vendita
- Il flag è stato creato con tipo, owner, descrizione, TTL e il ticket richiesto.
- Le regole di targeting sono definite; 'deny'per le regioni/ruoli indesiderati.
- Sticky bucketing è minato; l'identificatore selezionato è stabile.
- Precursori e bandiere health sono pronti; default sicuro.
- Dashboard e alert per p95/p99, error _ rate, business guardrails.
- Catofo automatico configurato; la soglia di stop rollout e le condizioni di rimborso.
- Piano canario: interessi/fasi/finestra di modifica/responsabile.
- Confighi valgono in CI; suddivisi in cluster/regioni.
- Documentazione di supporto/prodotto; playbook di incidenti.
- Piano di rimozione dei rami di codice e del flag stesso dopo il 100%.
16) Esempio di bandiera «migratoria» (database/indice)
yaml flag:
key: "search. use_index_v2"
type: "migration"
description: "Switching reads to index v2"
prerequisites:
- key: "search. index_v2_built"
must_be: "on"
rules:
- when: { tenant_id: ["brand_eu"], user_pct: 5 } then: "on"
- when: { tenant_id: ["brand_eu"], user_pct: 25 } then: "on"
safeguards:
auto_rollback_on:
search_p95_ms: ">180"
error_rate: ">1%"
ttl: "2026-02-01"
Conclusione
La feature Flags non è solo un'attivazione/disattivazione ", ma una disciplina per la gestione dei rischi di cambiamento. I tipi chiari di bandiere, il targeting determinatosi, le registrazioni progressive con guardrail, autoscafo, controllo e piano di rimozione rendono prevedibili i comunicati e gli incidenti sono brevi e controllati. Inserite le bandiere nell'architettura come prima classe di cittadini e potrete portare valore più spesso, più sicuro e più sensibile.