Skip to content

Горизонтальное масштабирование

SuperBotGo поддерживает запуск нескольких экземпляров для отказоустойчивости и распределения нагрузки. Каждая платформа имеет свой механизм масштабирования.

Проблема

Если просто запустить N экземпляров с одним токеном бота:

ПлатформаЧто произойдёт
Telegram (long polling)Telegram вернёт HTTP 409 — только один экземпляр может поллить
Discord (gateway)Все N экземпляров получат каждое событие — N-кратная обработка
VK (longpoll)Режим не подходит для multi-instance; для горизонтального масштабирования используйте callback
Mattermost (websocket)Все N экземпляров получат одни и те же события — нужна дедупликация

SuperBotGo решает это четырьмя механизмами: webhook-режим для Telegram, callback-режим для VK, шардинг для Discord и дедупликация для платформ, где событие может увидеть больше одного экземпляра.

Telegram: Webhook Mode

В webhook-режиме Telegram отправляет обновления на один HTTPS-эндпоинт. Load balancer распределяет запросы между экземплярами — каждый update попадает ровно на один из них.

Конфигурация

yaml
telegram:
  token: "123:ABC"
  mode: webhook
  webhook_url: "https://bot.example.com/tg/webhook"
  webhook_secret: "random-secret-string"
  webhook_listen: ":8443"

Или через переменные окружения:

bash
BOT_TELEGRAM_MODE=webhook
BOT_TELEGRAM_WEBHOOK__URL=https://bot.example.com/tg/webhook
BOT_TELEGRAM_WEBHOOK__SECRET=random-secret-string
BOT_TELEGRAM_WEBHOOK__LISTEN=:8443
ПараметрОбязателенОписание
modeнетpolling (по умолчанию) или webhook
webhook_urlпри webhookПубличный HTTPS URL, который Telegram будет вызывать
webhook_secretнетСекретный токен для валидации запросов (заголовок X-Telegram-Bot-Api-Secret-Token)
webhook_listenнетЛокальный адрес HTTP-сервера вебхука, например :8443

TIP

Для dev-окружения используйте mode: polling — не нужен публичный URL. Webhook предназначен для продакшена.

WARNING

При переключении между режимами Telegram запоминает последнюю настройку. Если бот работал в webhook-режиме, а вы переключили на polling — предварительно удалите webhook через Telegram API:

bash
curl "https://api.telegram.org/bot<TOKEN>/deleteWebhook"

Discord: Шардинг

Discord Gateway отправляет события через WebSocket. Без шардинга каждый экземпляр получает все события. Шардинг распределяет гильдии между экземплярами по формуле guild_id >> 22 % shard_count == shard_id.

Конфигурация

yaml
discord:
  token: "Bot TOKEN"
  shard_id: 0
  shard_count: 3
ПараметрОбязателенОписание
shard_idнетИндекс шарда, 0-based (по умолчанию 0)
shard_countнетОбщее количество шардов (по умолчанию 1 — без шардинга)

INFO

Discord обязывает использовать шардинг при >2500 серверов. Но включить его можно на любом масштабе для повышения отказоустойчивости.

Каждый экземпляр должен получить уникальный shard_id через конфиг или переменную окружения BOT_DISCORD_SHARD__ID.

WARNING

При изменении shard_count все экземпляры должны быть перезапущены одновременно — Discord требует единого shard_count для всех соединений одного бота.

VK: Callback Mode

Для single-instance можно использовать longpoll, но для горизонтального масштабирования нужен callback-режим. В этом режиме VK отправляет HTTP callbacks на публичный endpoint, а load balancer распределяет запросы между экземплярами.

Конфигурация

yaml
vk:
  token: "YOUR_VK_COMMUNITY_TOKEN"
  mode: callback
  callback_url: "https://bot.example.com/vk/callback"
  callback_path: "/vk/callback"
ПараметрОбязателенОписание
modeнетlongpoll (по умолчанию) или callback
callback_urlпри callbackПубличный URL, который VK вызывает для доставки событий
callback_pathнетЛокальный HTTP path, который монтирует SuperBotGo

TIP

Для production с несколькими экземплярами используйте mode: callback. longpoll оставляйте для dev или single-instance установки.

Mattermost: WebSocket + Dedup

Mattermost доставляет события через WebSocket. При нескольких экземплярах каждое подключение получает один и тот же поток событий, поэтому масштабирование здесь опирается на Redis-дедупликацию, а не на шардирование.

Интерактивные действия (post actions) приходят уже по HTTP и могут безопасно проходить через load balancer на любой экземпляр, если настроены actions_url и actions_secret.

WARNING

У Mattermost в текущей реализации нет отдельного механизма partitioning вроде Discord sharding. При росте нагрузки несколько экземпляров уменьшают SPOF, но не снижают fan-out входящих websocket-событий.

Дедупликация

Даже с webhook, callback и шардингом возможны дубли: Telegram повторяет webhook при таймауте, Discord переотправляет события при реконнекте, Mattermost и некоторые multi-connection сценарии дают одинаковые события нескольким экземплярам. SuperBotGo автоматически дедуплицирует обновления через Redis.

Как это работает

  1. Каждое входящее обновление получает PlatformUpdateID — уникальный идентификатор от платформы (например, tg:123456789 или dc:msg:1234567890)
  2. Перед обработкой middleware выполняет SET NX в Redis с TTL 5 минут
  3. Если ключ уже существует — обновление пропускается (другой экземпляр уже обработал)
  4. Если Redis недоступен — обновление обрабатывается (fail-open)

Дедупликация включена по умолчанию и не требует настройки. Нагрузка на Redis минимальна: каждый ключ занимает ~40 байт и живёт 5 минут.

Справочник конфигурации

Полный список параметров, связанных с масштабированием:

ПараметрEnvПо умолчаниюОписание
telegram.modeBOT_TELEGRAM_MODEpollingРежим получения обновлений
telegram.webhook_urlBOT_TELEGRAM_WEBHOOK__URLПубличный URL для webhook
telegram.webhook_secretBOT_TELEGRAM_WEBHOOK__SECRETСекрет для валидации
telegram.webhook_listenBOT_TELEGRAM_WEBHOOK__LISTENЛокальный адрес вебхук-сервера
discord.shard_idBOT_DISCORD_SHARD__ID0Индекс шарда
discord.shard_countBOT_DISCORD_SHARD__COUNT1Общее количество шардов
vk.modeBOT_VK_MODElongpollРежим получения обновлений
vk.callback_urlBOT_VK_CALLBACK__URLПубличный URL для callback
vk.callback_pathBOT_VK_CALLBACK__PATH/vk/callbackЛокальный path callback handler
mattermost.actions_urlBOT_MATTERMOST_ACTIONS__URLПубличный URL для interactive actions
mattermost.actions_pathBOT_MATTERMOST_ACTIONS__PATH/mattermost/actionsЛокальный path action handler
mattermost.actions_secretBOT_MATTERMOST_ACTIONS__SECRETСекрет валидации interactive actions

Что дальше?