Кластер

Кластер

0.4 NEW — Кластер v2: управление нодами из админки, latency-aware маршрутизация, правила по балансёрам, статистика и виджет доступности для пользователей.

Кластерный режим объединяет несколько серверов Al(co)pac в каскад. Один сервер (primary) принимает запросы от клиентов и распределяет нагрузку на бэкенд-серверы (nodes) по выбранной стратегии.

Архитектура

                 +-------------+
  Клиенты  --->  |   Primary   |  ← единая точка входа, авторизация, балансировка
                 |  (основной) |
                 +--+----+--+--+
                    |    |  |
           +--------+    |  +--------+
           |             |           |
           v             v           v
      +---------+   +---------+   +---------+
      | Node 1  |   | Node 2  |   | Node 3  |
      +---------+   +---------+   +---------+
       балансёры     балансёры     балансёры
  • Primary — принимает все запросы от клиентов, аутентифицирует пользователя, распределяет нагрузку
  • Node — выполняет запросы к балансёрам/CDN, стримит контент. Доверяет primary по общему ключу

Модель доверия

Primary авторизует, ноды доверяют. Только primary держит базу пользователей и проверяет токены. Ноды НЕ знают про пользователей — они доверяют заголовку X-Cluster-Key от primary и пропускают TG-auth/WAF.

Когда primary форвардит запрос на ноду:

  1. Primary валидирует пользователя (TG-токен, устройство, бан-лист)
  2. Добавляет X-Cluster-Key (общий секрет) и форвардит на ноду
  3. Нода видит валидный X-Cluster-Key → пропускает auth/WAF, обрабатывает запрос
  4. Нода возвращает результат, primary стримит его клиенту

Из этого следует два обязательных общих секрета:

СекретЗачем
cluster.api_keyАутентификация нод перед primary (доверие к форвардам)
proxy_link.shared_secretЕдиный AES-ключ для /proxy/ ссылок — без него стримы между нодами не расшифруются

Быстрый старт

1. Включить primary

В config.toml основного сервера:

[cluster]
enable = true
mode = "primary"

api_key и shared_secret можно не задавать вручную — они сгенерируются автоматически при добавлении первой ноды через админку (см. ниже).

2. Добавить ноду через админку

Админка → вкладка 🌐 Кластер➕ Добавить ноду:

  • Имя — читаемое название (например RU-SPB)
  • Хостhttp://IP:PORT ноды
  • Вес — относительный вес для распределения (по умолчанию 1)
  • Регион — опционально (RU, EU, …)

При первом добавлении primary автоматически:

  • генерирует cluster.api_key и proxy_link.shared_secret
  • записывает их в свой config.toml
  • показывает готовый блок для копирования на ноду

3. Настроить ноду

Скопируй блок из модала (кнопка 🔐 Секреты для нод) в config.toml ноды:

[cluster]
enable = true
mode = "node"
api_key = "<сгенерированный-ключ>"

[proxy_link]
shared_secret = "<сгенерированный-секрет>"

Перезапусти ноду. Через ~30 секунд (один цикл health-probe) она станет ● Healthy в админке.

api_key и proxy_link.shared_secret должны точно совпадать на primary и всех нодах. Без shared_secret ссылки /proxy/<hash> не расшифруются на ноде → битый стрим (404 / connection closed).

Хранилище

Ноды и настройки кластера хранятся в JSON (не только в config.toml):

  • database/cluster/nodes.json — список нод (имя, хост, вес, регион, enabled)
  • database/cluster/settings.json — стратегия, пороги, правила маршрутизации

При первом старте ноды из [[cluster.nodes]] в config.toml импортируются в JSON-стор (одноразовая миграция). Дальше всё управляется из админки в рантайме — без перезапуска.

Стратегии распределения

Настраиваются в админке (🌐 Кластер → ⚙️ Настройки):

СтратегияЛогика
hybrid (по умолчанию)Комбинирует активные соединения + latency. Вес latency настраивается (0..1)
least-connsНа ноду с наименьшим числом активных соединений (с учётом веса)
latencyНа ноду с минимальным пингом (EWMA)

Primary конкурирует с нодами: когда primary не загружен, он обрабатывает запросы локально. Под нагрузкой — отдаёт ноде.

Тестовый режим в настройках принудительно форвардит все запросы на ноды (игнорирует primary при выборе) — удобно проверить что трафик реально доходит до нод.

Правила маршрутизации

Можно закрепить конкретные балансёры за конкретными нодами или за primary. Правила имеют приоритет над стратегией. См. Маршрутизация.

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

  • Health-probe каждые 30с (GET /api/cluster/ping). После N неудач (по умолчанию 3) нода помечается down и исключается из выбора
  • Восстановление — после N успешных probe (по умолчанию 2) нода возвращается в строй. Состояние переживает рестарт (healthcheck.json)
  • Retry on 5xx — если нода вернула 5xx/dial-error в середине запроса, primary автоматически пробует следующую лучшую ноду (до max_retries)

Что распределяется

Тип запросаРаспределение
Балансёры (/lite/*)Да — основная нагрузка
Browser-сессии (Mirage, Alloha)Да
TMDB proxyНет — каждая нода кэширует локально
Статика, авторизацияНет — только primary

Видимость для пользователей

  • Мониторинг и статистика — что показывает админка
  • Публичный дашборд /servers и API /api/servers/info, /api/servers/list
  • Плагин server_widget — раздел «Серверы» в настройках Lampa с инфографикой по доступности

Требования

  • Все ноды доступны по сети с primary
  • cluster.api_key совпадает на всех серверах
  • proxy_link.shared_secret совпадает на всех серверах
  • Ноды могут иметь разные токены балансёров (для обхода rate-limits)
  • За reverse-proxy (nginx/caddy) обязательно пробрасывать Host и X-Forwarded-Proto:
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;