Каждый разработчик сталкивался с лимитом 6 HTTP/1.1 соединений на домен. При высокой нагрузке это даёт рост latency и деградацию RPS. HTTP/2 решает проблему одним соединением с параллельными потоками, но полный контроль даёт только работа через h2.
Почему aiohttp + h2
aiohttp нормально работает с HTTP/2 через TLS. Поднимая кастомный протокол, можно управлять приоритетами потоков. Это критично, когда одни запросы должны лететь раньше других, например, для real-time API и фоновых микросервисов.
Пример реализации
import aiohttp
from h2.config import H2Configuration
from h2.connection import H2Connection
async def handle_h2(r):
config = H2Configuration(client_side=False)
conn = H2Connection(config=config)
conn.initiate_connection()
# ... парсинг событий
if event.stream_id == 1:
conn.prioritize(event.stream_id, weight=256)
# отправка ответа
conn.send_headers(event.stream_id, [(':status', '200')])
Код — базовая инициализация, приём данных и разбор событий. Важный момент: для
stream_id = 1 ставится максимальный вес приоритета. Остальные потоки обрабатываются по дефолту. Ответ шлётся в том же цикле без корутин.Типичная ошибка и trade-offs
Мультиплексирование даёт прирост RPS в 5-10 раз на одном соединении, почти не увеличивая потребление памяти. Но отладка — ад: h2 поддерживает только TLS (готовьте сертификаты). Кастомные приоритеты могут вести себя неочевидно — документация h2 скупая, а протокол гибкий.
Практический совет: для микросервисов с кучей мелких запросов, чатов или прокси используйте h2, если упёрлись в лимит соединений. Минус — больше кода, чем с aiohttp-клиентом. Плюс — снижение latency за счёт одного TLS-хендшейка вместо шести.
Вывод: HTTP/2 мультиплексирование через h2 даёт контроль над приоритетами и пробивает лимиты соединений, но требует глубокого понимания протокола и готовности к сложной отладке.