May 26

🚩Какая польза от Feature Flags 🚩

Что самое мощное в этом инструменте? Включение какого-то функционала? Я уверен, что не только.

Вообще, давно хочу раскрыть такую тему как Фича-флаги (или feature flags, feature toggles). Тема хоть и старая, но актуальная и интересная. Они бывают статические, т.е. устанавливаются на этапе сборки проекта, и динамические, это когда можно менять прямо в рантайме поведение приложения.

Соответственно, реализация может быть

🧩 через конфиг (env, обычный файлик с конфигами)

🧩 через штатную базу данных проекта (обычно это реляционная СУБД)

🧩 через in-memory DB (redis, memcache etc.)

🧩 через 3d-party приложение (LaunchDarkly, Flagsmith и т.д.). В Gitlab (правда в Premium) тоже можно, кстати.

🧩 своё решение 🧠 - тут уже кто на что способен.

Соответственно, статические это быстро и дёшево, но не гибко. Нужно включить - передеплоивай приложение. Ну это ладно, это пол беды. Чтобы закатить что-то обратно - тоже нужно передеплоить. Это уже больнее.

С динамическими этот процесс проще - поменял стейт флага, что-то включилось, поменял обратно - выключилось. И никаких передеплоев. Красота. Включить или выключить функционал сильно проще, чем запускать сборку, деплой и прочее. Особенно, если у вас целый пайплайн из процессов для того чтобы выкатить одну строчку. Особенно, если нужно отключить фичу.

🎢 Плавный rollout.

Это одно из моих самых любимых.

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

В коде можно что-то типа такого сделать

<?php

final class FeatureRollout
{
    public function __construct(
        private readonly int $percentage // 0–100
    ) {
        if ($this->percentage < 0 || $this->percentage > 100) {
            throw new InvalidArgumentException('Percentage must be between 0 and 100.');
        }
    }

    public function isFeatureEnabledFor(string $userIdentifier): bool
    {
        $hash = crc32($userIdentifier);
        $bucket = $hash % 100;

        return $bucket < $this->percentage;
    }
}

$rollout = new FeatureRollout(30); // включено для 30% пользователей

$userId = 'some-uuid';

if ($rollout->isFeatureEnabledFor($userId)) {
    echo 'Показать новую фичу';
} else {
    echo 'Оставить старое поведение';
}

тогда конфигурироваться должно и состояние флага, и процент раскатки.

По категориям

🔥 Release Toggles - позволяют интегрировать незавершённые функции в основную ветку кода, отключая их до готовности к релизу.

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

🔥 Experiment Toggles - используются для A/B-тестирования и оценки пользовательских реакций на различные варианты функциональности.

🔥 Ops Toggles - предоставляют возможность оперативного включения или отключения функций в зависимости от условий эксплуатации или производительности системы.

Ну тут всё понятно. Самый кайф.

🔥 Permissioning Toggles - ограничивают доступ к определённым функциям для конкретных групп пользователей, например, только для премиум-клиентов.


По стратегии использования

🧩 Краткосрочные - для временного использования и должны быть удалены после завершения эксперимента (расктаки).

🧩 Долгосрочные - требуют постоянного управления и документирования. Они с нами надолго.

Как обычно, у любого инструмента есть своя цена

⚠️ Сложность тестирования - yвуличие множества флагов может привести к комбинаторному взрыву вариантов для тестирования. Необходимо тщательно планировать стратегии тестирования.

⚠️ Технический долг - неудалённые или устаревшие флаги увеличивают сложность системы и могут привести к ошибкам. Важно регулярно проводить ревизию и удалять неиспользуемые флаги. В одной компании у нас через какое-то время после раскатки приходил бот и ставил задачу на выпиливание флага.

⚠️ Если используем внешнюю систему, то нужно позаботится о кешировании флагом и об инвалидации кеша. Либо как хранить флаги поближе к коду. Ходить по http - не вариант.

-

Давайте оставаться на связи