Кластер
Кластерный режим объединяет несколько серверов Al(co)pac в каскад. Один сервер (primary) принимает запросы от клиентов и распределяет нагрузку на бэкенд-серверы (nodes) по выбранной стратегии.
Архитектура
+-------------+
Клиенты ---> | Primary | ← единая точка входа, авторизация, балансировка
| (основной) |
+--+----+--+--+
| | |
+--------+ | +--------+
| | |
v v v
+---------+ +---------+ +---------+
| Node 1 | | Node 2 | | Node 3 |
+---------+ +---------+ +---------+
балансёры балансёры балансёры- Primary — принимает все запросы от клиентов, аутентифицирует пользователя, распределяет нагрузку
- Node — выполняет запросы к балансёрам/CDN, стримит контент. Доверяет primary по общему ключу
Модель доверия
X-Cluster-Key от primary и пропускают TG-auth/WAF.Когда primary форвардит запрос на ноду:
- Primary валидирует пользователя (TG-токен, устройство, бан-лист)
- Добавляет
X-Cluster-Key(общий секрет) и форвардит на ноду - Нода видит валидный
X-Cluster-Key→ пропускает auth/WAF, обрабатывает запрос - Нода возвращает результат, 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. Правила имеют приоритет над стратегией. См. Маршрутизация.
Отказоустойчивость
- 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;