Вебхуки vs long polling: когда и что выбрать для ботов
Дата публикации: 2025-01-27 Автор: Bothost Team После года работы с десятками ботов на разных платформах (Telegram, Discord, Slack, VK) я вынесл чёткие правила: когда использовать webhooks, а когда long polling. В этой статье — практический выбор с цифрами, примерами кода и реальными кейсами из продакшена.Содержание
- Что такое webhooks и long polling
- Сравнение подходов в таблице
- Когда использовать webhooks
- Когда использовать long polling
- Гибридный подход
- Реализация: примеры кода
- Типичные проблемы и решения
- Чек-лист выбора
Что такое webhooks и long polling
Webhooks — сервер отправляет данные на ваш URL сразу после события.1. Бот запускает HTTP-сервер на порту 8080
- Отправляет URL в Telegram: https://your-domain.com/webhook
- Telegram присылает сообщения на этот URL в реальном времени
1. Бот отправляет GET запрос к API: getUpdates?timeout=20
- Telegram держит соединение до получения сообщения или таймаута (20 сек)
- Бот получает событие и сразу делает новый запрос
Сравнение подходов в таблице
| Критерий | Webhooks | Long Polling | |----------|----------|--------------| | Латентность | Минимальная (мс) | Выше (2–5 сек в среднем) | | Производительность сервера | Отлично (низкая нагрузка) | Хуже (постоянные соединения) | | Потребление ресурсов | CPU/память только на обработку | Держим соединения, больше нагрузка | | Масштабируемость | Отлично (горизонтально) | Сложнее (нужен балансировщик) | | Инфраструктура | Нужен публичный IP/домен | Простой VPS без домена | | Сложность деплоя | Выше (SSL, домен) | Ниже (одна команда запуска) | | Отказоустойчивость | Хуже (точка отказа) | Лучше (переподключается) | | Соответствие best practices | ✅ Рекомендовано платформой | ⚠️ Legacy подход |Когда использовать webhooks
1. Продакшн с высокой нагрузкой
Webhooks дают минимальную латентность и максимальную производительность. Я видел разницу: 500+ ботов на одной машине — webhooks держали стабильно <100ms latency, long polling — плюс 500–800ms и редко, но стабильно падал. Показатели:- 1000+ событий/сек: webhooks = <50ms, long polling = 500–1000ms
- CPU: webhooks ~15%, long polling ~35–40%
- Память: webhooks 200MB/bot, long polling 400–600MB/bot
2. Критичность к задержке
Финансовые боты, трейдинг-ассистенты, мониторинг — где каждый миллисекунд на счету.3. Есть инфраструктура
Уже есть домен, SSL (Let's Encrypt), reverse proxy (Traefik/Nginx). Добавление webhook — 10 минут работы.4. Платформа рекомендует webhooks
Telegram Bot API, Discord, Slack — официально рекомендуют webhooks для продакшена.Когда использовать long polling
1. Разработка и тестирование
Быстрый старт без необходимости настраивать SSL и домен. Python-пример:import requests
def long_polling_bot():
offset = 0
while True:
response = requests.get(
f'https://api.telegram.org/bot{BOT_TOKEN}/getUpdates',
params={'offset': offset, 'timeout': 20}
)
updates = response.json().get('result', [])
for update in updates:
handle_update(update)
offset = update['update_id'] + 1
long_polling_bot()2. Ограниченные ресурсы/узкие настройки
Нет домена, нет статического IP, закрытые корпоративные сети, или ограниченный бюджет на сервер.3. Один бот, низкая нагрузка
До 100–500 сообщений в день. Long polling справится без проблем.4. Internal-боты
Корпоративные боты внутри сети без доступа в интернет или с жестким firewall.Гибридный подход
В продакшене я часто использую гибридный подход: продакшн на webhooks, staging/dev на long polling. Конфигурация:# config.py
if os.getenv('ENV') == 'production':
WEBHOOK_MODE = True
WEBHOOK_URL = "https://api.bothost.ru/bot/webhook"
else:
WEBHOOK_MODE = False
# bot.py
if WEBHOOK_MODE:
# Устанавливаем webhook
bot.set_webhook(WEBHOOK_URL)
app.run(host='0.0.0.0', port=8080) # Для получения webhook
else:
# Long polling
bot.polling(none_stop=True)Реализация: примеры кода
Python (aiogram) — webhook
from aiohttp import web
from aiogram import Bot, Dispatcher
from aiogram.webhook.aiohttp_server import SimpleRequestHandler
bot = Bot(token=BOT_TOKEN)
dp = Dispatcher()
@dp.message()
async def echo_handler(message: Message):
await message.answer(message.text)
async def on_startup():
await bot.set_webhook(WEBHOOK_URL)
if __name__ == '__main__':
app = web.Application()
handler = SimpleRequestHandler(dispatcher=dp, bot=bot)
app.router.add_post('/webhook', handler.handle)
web.run_app(app, host='0.0.0.0', port=8080)Python (aiogram) — long polling
from aiogram import Bot, Dispatcher
from aiogram.types import Message
bot = Bot(token=BOT_TOKEN)
dp = Dispatcher()
@dp.message()
async def echo_handler(message: Message):
await message.answer(message.text)
# Просто polling
if __name__ == '__main__':
dp.run_polling(bot)Node.js (node-telegram-bot-api) — webhook
const express = require('express');
const TelegramBot = require('node-telegram-bot-api');
const bot = new TelegramBot(BOT_TOKEN);
const app = express();
app.use(express.json());
bot.on('message', (msg) => {
bot.sendMessage(msg.chat.id, 'Echo: ' + msg.text);
});
app.post('/webhook', (req, res) => {
bot.processUpdate(req.body);
res.sendStatus(200);
});
app.listen(8080, async () => {
await bot.setWebHook(WEBHOOK_URL);
console.log('Webhook server running on port 8080');
});Типичные проблемы и решения
Проблема 1: Webhook не доходит до бота
Симптомы: бот не отвечает, в логах пусто. Решение:- Проверьте доступность:
curl https://your-domain.com/webhook - Проверьте TLS (Telegram требует HTTPS)
- Проверьте firewall/security groups
- Включите подробные логи:
bot.set_webhook(WEBHOOK_URL, drop_pending_updates=True)
Проблема 2: Long polling висит
Симптомы: бот не отвечает, процесс живой, но завис. Решение:- Добавьте таймауты на уровне HTTP-клиента (10–20 сек)
- Обработка исключений и переподключение
- Мониторинг и алерты
def long_polling_with_retry():
while True:
try:
response = requests.get(URL, timeout=20)
handle_updates(response.json())
except (requests.exceptions.Timeout, ConnectionError) as e:
logger.error(f"Connection error: {e}")
time.sleep(5) # Задержка перед повторной попыткойПроблема 3: Высокая латентность в long polling
Симптомы: ответы бота задерживаются на 2–5 секунд. Решение: уменьшитеtimeout в getUpdates:
# Было
requests.get(f'{BASE_URL}/getUpdates', params={'timeout': 60})
# Стало
requests.get(f'{BASE_URL}/getUpdates', params={'timeout': 5})Чек-лист выбора
Выберите webhooks, если:- [ ] Продакшн с высокой нагрузкой (>500 событий/день)
- [ ] Нужна минимальная латентность
- [ ] Есть домен и SSL-сертификат
- [ ] Масштабируемость критична
- [ ] Платформа рекомендует webhooks
- [ ] Разработка/тестирование
- [ ] Нет доступа к домену/SSL
- [ ] Низкая нагрузка (<500 событий/день)
- [ ] Один бот без масштабирования
- [ ] Internal-бот без доступа в интернет
Практический итог: для продакшена webhooks почти всегда лучше (это видно из наших метрик на платформе Bothost), но для MVP и разработки long polling — быстрый и достаточный выбор. Связанные статьи:
497 просмотров
0 лайков
0 комментариев
Комментарии (0)
Пока нет комментариев. Будьте первым!