Webhook, polling, SSE, WebSocket для системного аналитика
Карьерник — Duolingo для аналитиков: 10 минут в день тренируй SQL, Python, A/B, статистику, метрики и ещё 3 темы собеса. 1500+ вопросов в Telegram-боте. Бесплатно.
Содержание:
Зачем сравнение спрашивают
Системный аналитик описывает интеграцию: внешняя система должна узнавать о событиях нашей. На собесе классический кейс: «банк должен получать уведомления о новых платежах. Опишите механизм». Ответ «отправлять каждые 10 секунд GET-запрос» — провал. Это polling, и он плохо масштабируется.
Главная боль без понимания вариантов — partner-команды строят polling на 1М запросов/день вместо webhook на 10k событий/день. Нагрузка вырастает в 100 раз без увеличения ценности. Аналитик должен знать матрицу: когда какой вариант.
Polling
Клиент периодически дёргает сервер с вопросом «есть что-то новое?»
Client: GET /events?since=12345 → 200 [empty]
... (через 10 сек)
Client: GET /events?since=12345 → 200 [event1, event2]
Client: GET /events?since=12347 → 200 [empty]Плюсы:
- Простейшая реализация
- Работает через любые прокси/firewall
- Stateless: сервер не помнит клиентов
Минусы:
- Большинство запросов пустые → пустая нагрузка на сеть и сервер
- Высокая latency: средняя задержка = половина интервала
- Не масштабируется: 1k клиентов × 1 запрос/сек = 1k RPS впустую
Когда применять: редкие события, простота важнее эффективности, нет возможности webhook (клиент не публичный).
Long-polling
Клиент шлёт запрос, сервер не отвечает сразу — ждёт события или таймаут.
Client: GET /events?since=12345 → (сервер ждёт 30 сек)
Server: → 200 [event1] (когда событие пришло)
Client: GET /events?since=12346 → (сервер ждёт)Плюсы:
- Меньше пустых запросов
- Низкая latency: событие приходит почти мгновенно
Минусы:
- Сервер держит открытое соединение per-client → шкалируется хуже polling по памяти
- Прокси/балансировщики могут резать долгие запросы (таймауты 30-60 сек)
- Сложнее мониторинг: «висит» — нормально или badly?
Используется в legacy чат-системах. В современных стеках вытеснен SSE и WebSocket.
Webhook
Сервер вызывает HTTP-endpoint клиента, когда событие происходит.
... (на нашей стороне произошёл платёж)
Server (наш): POST https://partner.com/webhooks/payments
{payment_id: 123, amount: 1000}
Client (партнёра): 200 OKПлюсы:
- Минимальный трафик: один запрос на событие
- Низкая latency: событие → доставка
- Сервер не держит соединения
Минусы:
- Партнёр должен быть публично доступен (или туннель/proxy)
- Нужна обработка retry/доставки (партнёр временно недоступен → повторять)
- Нет гарантии порядка (если несколько событий за секунду — могут прийти не в том порядке)
- Безопасность: HMAC подпись, проверка origin
Стандарт описания в ТЗ:
- URL endpoint партнёра, метод (обычно POST)
- Формат тела (JSON schema, Avro)
- Подпись (HMAC SHA-256 заголовок)
- Retry-policy: коды для ретраев (5xx, 408, 429), backoff, max attempts, dead-letter queue
- Idempotency-key для дедупликации при ретраях
- Versioning: как добавляем новые поля без поломки старых клиентов
Server-Sent Events (SSE)
HTTP-based unidirectional stream сервер → клиент.
Client: GET /events
Accept: text/event-stream
Server: HTTP/1.1 200 OK
Content-Type: text/event-stream
data: {"id": 1, "amount": 100}\n\n
data: {"id": 2, "amount": 200}\n\n
...Плюсы:
- Native в браузерах через
EventSource - Авто-reconnect и last-event-id (после сбоя клиент продолжит с того же места)
- Простая реализация на сервере (просто HTTP-ответ с keep-alive)
- Кеши/proxy дружественны (это HTTP)
Минусы:
- Только сервер → клиент, не bidirectional
- Только текст/UTF-8 (бинарь — base64)
- Не подходит для мобильных приложений напрямую (хотя есть библиотеки)
Когда применять: stock tickers, push notifications в браузере, live feed, прогресс долгой задачи.
WebSocket
Двусторонний (full-duplex) канал поверх TCP, начинается с HTTP upgrade.
Client: GET /ws
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: ...
Server: HTTP/1.1 101 Switching Protocols
Upgrade: websocket
(после этого — бинарные/текстовые фреймы в обе стороны)Плюсы:
- Bidirectional: и сервер, и клиент могут отправлять
- Низкая latency, бинарь поддерживается
- Поддерживается всеми современными браузерами
- Один канал на множество событий
Минусы:
- Сервер держит соединение → memory per-client
- Не stateless → балансировщики L7 нужны с sticky sessions
- Не кешируется через CDN
- Прокси-настройки иногда блокируют (HTTPS upgrade through proxy)
- Сложнее реализация и operations
Когда применять: чат, multiplayer-игры, collaborative editing, торговля в реальном времени, диспетчерские системы.
Матрица выбора
| Сценарий | Выбор |
|---|---|
| Партнёрская система получает редкие события (платежи, статусы заказов) | Webhook |
| Браузер показывает live-обновления (тикер, fee live) | SSE |
| Чат, многопользовательская игра | WebSocket |
| Мобилка, несколько событий в час | Push-уведомления (FCM/APNS) или polling |
| Партнёр не имеет публичного endpoint | Polling или long-polling |
| Прогресс долгой задачи в браузере | SSE или polling по статусу |
| Контроль над сервером невелик, инфра простая | Polling |
| Bidirectional низколатентное взаимодействие | WebSocket |
Частые ошибки
Polling вместо webhook когда возможно. Если партнёр имеет публичный URL — webhook эффективнее на 1-2 порядка.
Не описывать retry в webhook. Партнёр упал, не получил → событие потеряно. Описать политику ретраев и dead-letter.
Webhook без HMAC-подписи. Любой может симулировать событие на endpoint партнёра. Подпись + verification обязательны.
WebSocket для редких событий. Открытое соединение на пустую переписку — ресурсы впустую. Push-уведомления или SSE достаточно.
SSE для bidirectional. SSE — только сервер → клиент. Если нужно двустороннее — WebSocket или комбинация SSE + POST.
Long-polling без таймаутов. Соединение висит часами, балансировщик режет, клиент думает «всё нормально». Явный таймаут (30-60 сек) и reconnect.
Webhook без idempotency. Партнёр получает webhook повторно после ретрая, начисляет бонус дважды. Idempotency-Key в headers + дедуп на стороне партнёра.
Связанные темы
- REST API на собесе SA
- HTTP методы и коды на собесе SA
- REST vs SOAP vs gRPC vs GraphQL
- Подготовка к собесу системного аналитика
- Сoбеседование системного аналитика
FAQ
Webhook это REST?
Не совсем. Webhook — это паттерн «обратного вызова» через HTTP. Технически — POST-запрос на endpoint клиента. Сам endpoint — REST-стиля (URL ресурса), но семантика — push.
WebSocket поверх HTTP?
Начало — HTTP upgrade (handshake). Дальше — TCP-соединение с собственным фреймовым протоколом. С точки зрения proxy — это HTTPS-туннель.
Что выбрать между SSE и WebSocket для уведомлений в браузере?
Если только сервер → клиент, текст, простая интеграция — SSE. Если нужны двусторонние сообщения, бинарь, низкая latency — WebSocket.
Как доставлять события мобильному приложению?
Push-уведомления (FCM для Android, APNS для iOS). Когда приложение открыто — может быть WebSocket для real-time чата. Polling — фоном при низкой важности.
Можно ли использовать WebSocket для машинных интеграций (server-to-server)?
Можно, но обычно избыточно. gRPC streaming, Kafka, webhooks — более стандартные решения для server-to-server. WebSocket чаще для browser-to-server.
Это официальная информация?
Нет. Статья основана на RFC 6455 (WebSocket), HTML5 SSE spec, общей практике интеграционной архитектуры.
Тренируйте системный анализ — откройте тренажёр с 1500+ вопросами для собесов.