Kravchenko

Web Lab

АудитБлогКонтакты

Kravchenko

Web Lab

Разрабатываем сайты и автоматизацию на современных фреймворках под ключ

Услуги
ЛендингМногостраничныйВизитка
E-commerceБронированиеПортфолио
Навигация
БлогКонтактыАудит
Обратная связь
+7 921 567-11-16
info@kravlab.ru
с 09:00 до 18:00

© 2026 Все права защищены

•

ИП Кравченко Никита Владимирович

•

ОГРНИП: 324784700339743

Политика конфиденциальности

Feature flags — быстрые эксперименты и безопасные релизы без отдельного сервиса

Разработка и технологии15 марта 2026 г.
Флаги функций (feature flags) позволяют включать и выключать поведение продукта без деплоя — это ускоряет релизы, снижает риски и даёт инструмент для A/B‑тестов. В статье — простая надёжная архитектура на PostgreSQL + Redis, примеры миграции и кода для проверки по процентам и сегментам.
Feature flags — быстрые эксперименты и безопасные релизы без отдельного сервиса

Содержание

  • Что такое feature flags и зачем они бизнесу
  • Быстрые сценарии использования
  • Архитектура: PostgreSQL как источник правды, Redis — для скорости
  • Стратегии включения: on/off, процентные релизы, таргетинг
  • Практическая реализация
    • схема таблицы и миграция (SQL)
    • кэш и проверка флага в Node.js (Express + Redis)
    • алгоритм процентного rollout
  • CI/CD: безопасность и удаление флагов
  • Ошибки, которых стоит избегать
  • Вывод

Что такое feature flags и зачем они бизнесу

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

  • Меньше откатов: можно выключить фичу мгновенно при проблемах.
  • Быстрые эксперименты: запуск A/B и проверка метрик на живых пользователях.
  • Градиентный релиз: открывать фичу частично для снижения рисков.
  • Разделение релиза и включения: релиз кода и активация — независимые процессы.

Быстрые сценарии использования

  • Включить новую корзину покупок только для 10% пользователей.
  • Активировать промо-баннер для пользователей из конкретного региона.
  • Выключить экспериментальную оплату при падении метрик.

Архитектура: PostgreSQL как источник правды, Redis — для скорости

Рекомендованная простая архитектура:

  • PostgreSQL — хранит конфигурацию флагов (история, владельцы, правила). Надёжно, транзакционно и удобно в миграциях.
  • Redis — кэш значений флагов для быстрого доступа в критическом коде (путём редиса мы уменьшаем нагрузку на БД и задержку).
  • Сервис админки/CI — для создания/редактирования флагов и управления lifecycle.

Преимущества: консистентность и простота, без отдельного коммерческого сервиса. Минусы: вам нужно реализовать rollout-логику и TTL/инвалидацию кэша.

Стратегии включения

  • On/Off — простой переключатель.
  • Процентный rollout — включать для случайной выборки пользователей (например, 5%, 20%).
  • Таргетинг по свойствам — включать по сегментам: страна, подписка, internal-букмарки.
  • Время/канарии — включить для internal-пользователей и затем постепенно расширять.

Практическая реализация

Схема таблицы и миграция (PostgreSQL)

-- Таблица флагов функций
CREATE TABLE feature_flags (
  key text PRIMARY KEY,
  enabled boolean NOT NULL DEFAULT false,
  rollout_percent integer NOT NULL DEFAULT 0, -- 0..100
  targeting jsonb DEFAULT '{}'::jsonb, -- произвольные правила, например {"countries": ["RU"]}
  updated_at timestamptz NOT NULL DEFAULT now()
);

-- История изменений (опционально)
CREATE TABLE feature_flag_events (
  id bigserial PRIMARY KEY,
  flag_key text NOT NULL REFERENCES feature_flags(key),
  action text NOT NULL,
  payload jsonb,
  created_at timestamptz NOT NULL DEFAULT now()
);

Пояснение: храните rollout_percent и targeting как простую структуру. Это даёт гибкость и лёгкость миграций.

Кэш и проверка флага в Node.js (Express + Redis)

Пример middleware: при запросе сначала проверяем Redis, если нет — читаем из Postgres и записываем в Redis с TTL.

// featureFlags.js
const crypto = require('crypto');
const { Pool } = require('pg');
const Redis = require('ioredis');

const pg = new Pool({ connectionString: process.env.DATABASE_URL });
const redis = new Redis(process.env.REDIS_URL);

// Хелпер — честный хеш для процентного rollout
function hashPercent(key, identifier) {
  const h = crypto.createHash('sha1').update(`${key}:${identifier}`).digest();
  // берем первые 4 байта как uint32
  const num = h.readUInt32BE(0);
  return (num / 0xffffffff) * 100; // 0..100
}

async function getFlagFromDb(key) {
  const res = await pg.query('SELECT enabled, rollout_percent, targeting FROM feature_flags WHERE key = $1', [key]);
  if (!res.rowCount) return null;
  return res.rows[0];
}

async function getFlag(key) {
  const cacheKey = `flag:${key}`;
  const cached = await redis.get(cacheKey);
  if (cached) return JSON.parse(cached);
  const row = await getFlagFromDb(key);
  // кешируем даже null на короткое время чтобы уменьшить нагрузку
  await redis.set(cacheKey, JSON.stringify(row), 'EX', 30);
  return row;
}

// Проверка флага для конкретного пользователя
async function isFlagEnabledFor(key, context = {}) {
  const f = await getFlag(key);
  if (!f) return false;
  if (f.enabled && (!f.rollout_percent || f.rollout_percent === 100)) return true;

  // таргетинг по простым правилaм (пример)
  if (f.targeting && f.targeting.countries) {
    const country = context.country;
    if (country && f.targeting.countries.includes(country)) return true;
  }

  // процентный rollout
  if (f.rollout_percent && context.userId) {
    const p = hashPercent(key, String(context.userId));
    return p < f.rollout_percent;
  }

  return false;
}

module.exports = { isFlagEnabledFor };

Использование в обработчике Express:

const express = require('express');
const { isFlagEnabledFor } = require('./featureFlags');
const app = express();

app.get('/checkout', async (req, res) => {
  const userId = req.user && req.user.id;
  const ctx = { userId, country: req.headers['x-country'] };
  if (await isFlagEnabledFor('new_checkout', ctx)) {
    return res.send('Новый checkout');
  }
  res.send('Старый checkout');
});

Алгоритм процентного rollout

  • Фиксируйте идентификатор (userId) как стабильную соль — иначе пользователи будут «прыгать» между группами.
  • Используйте криптографический хеш (SHA1/SHA256) и нормализацию в диапазон 0..100.
  • Проверяйте таргетинг до процентной проверки — если пользователь в целевой группе, дать доступ независимо от процента.

CI/CD: управление и удаление флагов

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

Ошибки, которых стоит избегать

  • Хранить логику rollout только в приложении без централизованной конфигурации — трудно отладить.
  • Забывать удалять устаревшие флаги — приводит к накоплению технического долга.
  • Полагаться на кэш без TTL/инвалидации при изменении флага — пользователи увидят рассинхронизацию.
  • Использовать нестабильные идентификаторы для процентного распределения — тогда сегментация неустойчива.

Вывод

Feature flags — недорогой инструмент в руках команды: они ускоряют выпуск фич, снижают риски и дают гибкость для экспериментов. Простая архитектура на PostgreSQL как «источнике правды» + Redis для быстрого доступа даёт баланс надёжности и производительности, а пара чистых правил для lifecycle (создание, владельцы, критерии успеха, удаление) минимизирует долг и инциденты.

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


релизыэкспериментыfeature-flags