Skip to content

Обзор SDK

SDK можно. — это клиентские библиотеки, которые загружают правила с сервера и локально оценивают фиче-флаги в вашем приложении.

Архитектура

graph TD
    subgraph "Ваше приложение"
        SDK[SDK mozhno]
        EVAL[Локальная оценка]
        CACHE[Кеш правил]
    end
    subgraph "Сервер mozhno"
        API[REST API]
        DB[(PostgreSQL)]
    end

    SDK -->|1. Загрузка правил| API
    API -->|2. Правила| SDK
    SDK -->|3. Сохраняет| CACHE
    SDK -->|4. Оценивает локально| EVAL
    SDK -->|5. Фоновый поллинг| API
    APP[Код приложения] -->|isEnabled?| SDK
    SDK -->|true/false| APP

Принцип локальной оценки

  1. Старт: SDK загружает все правила флагов с сервера один раз.
  2. Кеширование: Правила сохраняются в памяти.
  3. Локальная оценка: Каждый вызов isEnabled() оценивается локально — без задержки сети.
  4. Фоновое обновление: SDK периодически опрашивает сервер (по умолчанию каждые 15 секунд) и обновляет кеш. Используется ETag / If-None-Match для эффективных дельта-обновлений.
ПреимуществоОписание
Нулевая задержкаОценка флага: доли микросекунды
Нет single point of failureЕсли сервер недоступен, SDK продолжает работать с закешированными правилами
МасштабируемостьСервер не нагружается запросами оценки флагов

Логика оценки

SDK оценивает флаг в следующем порядке:

  1. Флаг выключен?false
  2. Нет стратегии/activation?true
  3. Ограничения (constraints): все правила должны совпасть с контекстом (И)
  4. Сегменты: хотя бы один сегмент должен совпасть (ИЛИ)
  5. Если есть и то, и другое: достаточно совпадения одного (ИЛИ)
  6. Процентный роллаут: MurmurHash32 от flagKey + (userId || sessionId), сравнение с процентом
  7. Ничего не совпалоfalse

Поддерживаемые операторы

ОператорОписание
inЗначение входит в список
not_inЗначение не входит в список
eqРавенство (числовое для contextType: number)
neНеравенство
gtБольше
gteБольше или равно
ltМеньше
lteМеньше или равно
containsПодстрока

Типы контекста

ТипПоведение
string (по умолчанию)Строковое сравнение
numberЧисловое сравнение
timeСравнение ISO8601 дат
semverСемантическое версионирование

Синхронизация правил

SDK использует механизм Polling (периодический опрос). Интервал по умолчанию — 15 секунд.

sequenceDiagram
    participant SDK
    participant Server

    SDK->>Server: GET /api/client/features (If-None-Match)
    Server-->>SDK: 200 + JSON (или 304 Not Modified)
    Note over SDK: Кеширование в памяти

    loop Каждые 15 секунд
        SDK->>Server: GET /api/client/features (If-None-Match)
        Server-->>SDK: 304 Not Modified (или обновлённые флаги)
        Note over SDK: Атомарное обновление кеша
    end
ПараметрЗначение по умолчаниюОписание
Интервал опроса15 секундrefreshInterval (JS) / fetchTogglesInterval (Java)
Retry при ошибкеЭкспоненциальный backoff1с → 2с → 4с
Circuit breaker (Java)5 ошибок → 60с паузаЗащита от перегрузки сервера

Инициализация клиента

Java SDK

java
MozhnoConfig config = MozhnoConfig.builder()
    .appName("my-app")
    .instanceId("instance-1")
    .mozhnoUrl("http://localhost:8080")
    .apiKey("<api-key>")
    .fetchTogglesInterval(15)
    .sendMetricsInterval(60)
    .environment("production")
    .build();

MozhnoClient client = new DefaultMozhnoClient(config);
client.start();
boolean enabled = client.isEnabled("new-checkout", context);

JavaScript / TypeScript SDK

typescript
import { MozhnoClient } from '@mozhno/client-js';

const client = new MozhnoClient({
  url: 'http://localhost:8080',
  apiKey: '<api-key>',
  appName: 'my-app',
  refreshInterval: 15,
  metricsInterval: 60,
  environment: 'production',
});

await client.start();
const enabled = client.isEnabled('new-checkout', { userId: 'user-123' });

Общие параметры конфигурации

ПараметрJS ключJava ключПо умолчаниюОписание
URL сервераurlmozhnoUrlОбязательноБазовый URL сервера
API-ключapiKeyapiKeyОбязательноAPI-ключ окружения
Имя приложенияappNameappNameОбязательноИдентификатор приложения
ID экземпляраinstanceIdinstanceIdОбязательно (Java)Уникальный ID инстанса
Интервал опроса (с)refreshIntervalfetchTogglesInterval15Частота поллинга
Интервал метрик (с)metricsIntervalsendMetricsInterval60Частота отправки метрик
Окружениеenvironmentenvironmentnull (Java) / "default" (JS)Имя окружения
Отключить метрикиdisableMetricsdisableMetricsfalseОтключение метрик

Контекст оценки

Контекст — это map атрибутов, описывающих текущий запрос или пользователя:

java
MozhnoContext context = MozhnoContext.builder()
    .userId("user-123")
    .sessionId("session-abc")
    .addProperty("country", "RU")
    .addProperty("plan", "premium")
    .build();
typescript
const context = {
  userId: 'user-123',
  sessionId: 'session-abc',
  country: 'RU',
  plan: 'premium',
};

Обработка ошибок и отказоустойчивость

Запуск SDK

СитуацияJava SDKJS SDK
Сервер доступен при стартеЗагружает правила, клиент готовЗагружает правила, клиент готов
Сервер недоступен при стартеВыбрасывает исключение при synchronousFetchOnInitialisation(true). Иначе — запускается и ретраит в фонеPromise отклоняется
Сервер стал недоступен в работеИспользуется закешированное состояние. Фоновые ретраиИспользуется закешированное состояние. Фоновые ретраи

Совет: В продакшене используйте synchronousFetchOnInitialisation(false) (по умолчанию) — SDK запустится даже если сервер временно недоступен при старте, и догонит правила при восстановлении связи.

Оценка флагов

СитуацияПоведение
Флаг не найденВозвращается false (fail-closed)
Флаг найден, кеш пустВозвращается false — безопасное поведение по умолчанию
Атрибут отсутствует в контекстеПравило с этим атрибутом возвращает false
Сеть недоступнаЗакешированные правила продолжают работать

Задержка обновлений

Изменения флага в веб-панели доходят до SDK за время polling-интервала (по умолчанию 15 секунд).

Поддерживаемые SDK

ЯзыкПакетДокументация
Javadev.mozhno:mozhno-client-java (Gradle)Java SDK
JavaScript / TypeScript@mozhno/client-js (npm)JS SDK

Что дальше?

Released under the AGPL v3.0 License.