Поллинг

В системном дизайне важно понимать, как именно клиент будет получать обновления от сервера. Если мы делаем чат, ленту котировок или статус доставки заказа — нам нужен real-time или его имитация. Самый базовый способ достичь этого — Polling.

Polling (Опрос) — это метод, при котором клиент по собственной инициативе периодически отправляет запросы к серверу: «Есть что-то новое? Нет. А сейчас? Нет. А сейчас?».

Основные характеристики Polling:

  • Инициатива клиента: Клиент сам решает, когда спрашивать сервер.
  • Периодичность: Запросы отправляются через регулярные интервалы времени.
  • Ожидание ответа: Клиент ждет ответа на каждый запрос (синхронно или асинхронно).
1. Простой Polling (Short Polling)

Клиент стучится на сервер через фиксированные интервалы (например, каждые 2 секунды). Сервер отвечает мгновенно: либо данными, либо статусом «ничего нового».

  • Плюсы: Максимально простая реализация на бэкенде.
  • Минусы: Огромная нагрузка. Если у тебя 1 млн пользователей и интервал 1 сек — это 1 млн RPS на сервер, даже если в системе ничего не происходит.
2. Длинный Polling (Long Polling)

Клиент отправляет запрос, но сервер не отвечает сразу. Он удерживает (вешает) соединение открытым до тех пор, пока не появятся новые данные или не истечёт таймаут (например, 30 секунд). Как только данные появились — сервер отвечает, клиент их обрабатывает и тут же открывает новый «длинный» запрос.

  • Плюсы: Почти мгновенное получение данных. В разы меньше пустых запросов по сети.
  • Минусы: Серверу нужно держать тысячи открытых TCP-соединений. Требует асинхронной архитектуры на бэкенде.
Python
# Пример Long Polling на стороне клиента
import requests

def long_polling():
    while True:
        try:
            # Запрос «зависнет» на сервере до появления данных
3. Регулярный Polling с Exponential Backoff

Если сервер упал или данных долго нет, глупо продолжать долбить его каждую секунду. Клиент плавно увеличивает паузу между запросами: 1с -> 2с -> 4с -> 8с... вплоть до лимита (например, 60с). Это спасает систему от «шторма запросов» (Thundering Herd), когда сервер пытается подняться после сбоя.

Python
# Пример Exponential Backoff
import time

interval = 1
while True:
    result = check_updates()
    if result:
4. Деталь реализации: Асинхронный Polling

Важно понимать: асинхронный поллинг — это не новый протокол, а способ написания кода на клиенте. Если твой микросервис должен поллить 1000 разных задач одновременно и делает это синхронно (через requests), он быстро исчерпает пул потоков.

  • Плюсы: Один процесс может держать тысячи соединений Long Polling одновременно, почти не потребляя память.
  • Минусы: Требует асинхронных библиотек.
Python
# Асинхронный клиент на aiohttp
import aiohttp
import asyncio

async def async_polling():
    async with aiohttp.ClientSession() as session:
        while True: