Технологии и Инфраструктура → Latency и оптимизация отклика API
Latency и оптимизация отклика API
1) Что такое «latency» и почему это важно
Latency — суммарная задержка запроса: сеть (DNS+TCP+TLS+RTT), балансер/шлюз, приложение, БД/кэши/очереди, внешние интеграции. Для бизнеса критичны P95/P99, а не среднее: именно «хвост» рушит UX, CR и SLO.
Базовые SLI:- `SLI_latency_P95 = P95(время_отклика)` за 5/30 минут
- `SLI_latency_P99 = P99(время_отклика)`
- `SLI_queue_time = P95(время_в_очереди_воркера)`
- `SLI_ext_call_P95 = P95(латентность_внешних_провайдеров)`
2) Карта источников задержек (и куда копать)
1. Сеть и протоколы: DNS, TCP handshakes, TLS, head-of-line (HTTP/1.1), потеря пакетов, BBR/ECN.
2. Шлюз/балансер: медленные health-check, невалидные таймауты, горячие поды.
3. Приложение: блокировки, GC/stop-the-world, синхронные I/O, contention.
4. Хранилища: медленные запросы БД, отсутствие индексов, холодные страницы.
5. Внешние сервисы: PSP/KYC, сторонние API (узкие SLA).
6. Очереди и фоновые джобы: перенагруженные воркеры, нет backpressure.
7. Кэш/edge: промахи кэша, слабый TTL, невалидная инвалидация.
3) Сеть и протоколы
3.1 DNS/TCP/TLS
DNS prefetch/preconnect на фронте, долгоживущие IP к PSP.
Keep-Alive/connection pooling в клиентах; на сервере — агрегируйте соединения.
TLS: resumption/Session Tickets, современный пакет шифров; избегайте 0-RTT для небезопасных идемпотентных операций.
TCP: отключите Nagle (`TCP_NODELAY`) для чатов/малых пакетов; tune `initial window`, включите BBR где уместно.
3.2 HTTP/2 и HTTP/3
HTTP/2: мультиплексирование уменьшает HOL-блокировки HTTP/1.1; следите за приоритетами потоков.
HTTP/3/QUIC: ниже влияние потерь/RTT; полезно на мобильной/международной сети.
Header compression: HPACK/QPACK, но сохраняйте разумный размер заголовков.
3.3 Балансировка/роутинг
Locality-aware (зональность), EWMA/least-request против «горячих» инстансов.
Залипание сессий — только если есть state; иначе stateless + общий кэш/сессии.
4) Форматы, полезная нагрузка, компрессия
Сжимайте: Brotli (текст), Gzip как fallback; бинарные форматы: Protobuf/Avro для gRPC/внутренних API.
Уменьшайте payload: выборочные поля (`fields=...`), пагинация, условные GET (ETag/If-None-Match), delta-ответы.
GraphQL: persisted queries, запрет «жирных» фрагментов, лимиты глубины и сложностей.
Избегайте N+1: джойны/прекомпозиция, батч-эндпоинты для агрегатов.
5) Таймауты, ретраи, идемпотентность
Таймауты по цепочке: клиент < шлюз < аппа < хранилище/внешний вызов.
Ретраи с backoff+jitter, только для временных ошибок; выставляйте budgets на ретраи.
Идемпотентность: ключ/токен запроса + сохранение результата; ретраи не должны дублировать операции (особенно финансы).
Circuit Breaker: открывайте при деградации; hedged/backup requests для «хвостов» (отправить дубликат через P95).
6) Очереди, асинхронность и backpressure
Не блокируйте синхронный путь: тяжелые операции (KYC сканы, отчетность) — в фон.
Backpressure: ограничивайте потребление из очереди, фиксируйте параллелизм.
Batching/coalescing: объединяйте мелкие операции (например, обновление балансов с агрегированием).
Outbox/Inbox: гарантированная доставка событий при отказах.
7) Приложение: рантаймы и пулы
Пулы соединений к БД/кэшам/HTTP; лимитируйте их, чтобы не «задушить» бэкенд.
JVM: профилируйте GC (G1/ZGC), избегайте крупных аллокаций;.NET — ThreadPool/async; Node.js — не блокируйте event loop, вынесите CPU-тяжелое.
Python: асинхронные драйверы (asyncpg/httpx), uvloop; CPU-задачи через worker-pool.
Warm-up: прогревайте JIT/кэши, «warm pools» инстансов к пикам.
8) Базы данных и кэши
Индексы и планы: регулярный `EXPLAIN`, авто-вакуум/анализ, лимит сканов.
Connection pooling (PgBouncer/Multiplexing), короткие транзакции.
Кэш-стратегии: read-through, write-through/write-behind; TTL + инвалидация по событиям.
Шардинг/реплики: чтение со слейвов, «горячие ключи» — локальные кэши (near-cache).
9) Кэширование и edge
CDN/edge для статик/каталогов, кэш API-ответов (если безопасно) по `Cache-Control`, `ETag`.
Stale-while-revalidate и stale-if-error для UX-устойчивости.
Geo-распределение: ближайший POP/регион снижает RTT.
10) Архитектурные паттерны против хвостов P99
Hedged requests: дублируйте медленный запрос на другой инстанс после порога.
Request collapsing: один «ведущий» запрос к БД, остальные ждут результат (избегает штормов).
Prioritization: VIP/критичные операции — выделенный пул/приоритет.
Graceful degradation: урезайте второстепенные поля/виджеты при перегрузке.
11) Конфиги (примерно)
11.1 NGINX (таймауты/компрессия)
nginx proxy_connect_timeout 1s;
proxy_send_timeout 2s;
proxy_read_timeout 2s;
send_timeout 2s;
gzip on;
gzip_types application/json text/plain text/css application/javascript;
11.2 Envoy (hedge + retry budget)
yaml
RetryPolicy:
retry_on: 5xx,reset,connect-failure num_retries: 2 per_try_timeout: 300ms retry_back_off: { base_interval: 50ms, max_interval: 200ms }
retry_priority:
name: envoy. retry_priorities. previous_priorities
HedgePolicy:
hedge_on_per_try_timeout: true initial_requests: 1 additional_request_chance: 0. 2
11.3 gRPC (клиент)
json
{
"methodConfig": [{
"name": [{"service": "payments. Service"}],
"timeout": "0. 8s",
"retryPolicy": {
"maxAttempts": 3,
"initialBackoff": "0. 05s",
"maxBackoff": "0. 2s",
"backoffMultiplier": 2. 0,
"retryableStatusCodes": ["UNAVAILABLE","DEADLINE_EXCEEDED"]
}
}]
}
12) Observability: меряйте правильно
RED/USE метрики + трейсы OTel: `trace_id` сквозь шлюз-сервис-БД-внешние API.
Отдельные метки: `api_version`, `region`, `partner`, `endpoint`.
Дашборды: P50/P95/P99, queue time, error mix, retry rate, cache hit.
Synthetics из целевых стран/ASN (TR/BR/EU) и по критичным путям (рег→депозит, payout).
- Core API: `P95 ≤ 250ms`, `P99 ≤ 500ms` (30 дней)
- PSP webhook обработка: `P99 ≤ 60s` с ретраями
- Freshness каталога: `P95 лаг ≤ 30s`
13) FinOps и latency
Миллисекунды стоят денег: оцените $/мс выигрыша в CR/ARPPU.
Right-sizing: быстрее ≠ дороже всегда; грамотный кэш/форматы дешевят и ускоряют.
Egress/edge: CDN уменьшает RTT и стоимость исходящего трафика из региона.
14) Чек-лист оптимизации (пошагово)
1. Поставьте SLO и замерьте хвосты (P95/P99) по эндпоинтам/регионам/партнерам.
2. Включите HTTP/2/3, TLS resumption, долгоживущие соединения.
3. Сожмите и похудейте ответы: Brotli/Gzip, поля по запросу, пагинация, ETag.
4. Настройте таймауты/ретраи/брейкеры; добавьте идемпотентность.
5. Кэш/edge: hit-rate и правильные TTL; stale-режимы.
6. БД: индексы, планы, пулы, реплики; устраните N+1.
7. Асинхроньте тяжелое: очереди, батчинг, backpressure.
8. Hedge/collapse/priority для критичных путей.
9. Warm-up и предиктивный скейлинг к пикам (турниры/матчи).
10. Синтетика и алерты на P99 и queue time; регулярные перф-ревью.
15) Анти-паттерны
Один глобальный таймаут «на все» и бесконтрольные ретраи (DDOS самого себя).
Залипание сессий без необходимости → горячие ноды.
Большие JSON без компрессии и фильтров полей.
Синхронные вызовы к медленным внешним API в «горячем пути».
Отсутствие индексов/лимитов в БД; N+1 в ORM.
Нет кэша/edge и ETag; постоянные полные ответы.
Микс бизнес-и технических ошибок в одну «ретраящуюся» корзину.
16) Контекст iGaming/финтех: практические ноты
Рег→депозит (CR): приоритет маршрутов, отдельный пул, `P99 ≤ 500ms`; деградация — отключать «украшения» UI.
PSP-интеграции: лимиты конкарренси, ретраи по временным кодам, warm-коннекты, региональные egress-IP.
VIP-операции: гарантированный пул/приоритет, обход общих очередей.
Турниры/ивенты: предиктивный скейл, прогрев кэшей, prefetch.
Отчетность: async и SLA на freshness, не блокирует прод-путь.
Итог
Оптимизация latency — это дисциплина баланса: сеть (HTTP/2/3, TLS), протоколы и кэш, таймауты/ретраи с идемпотентностью, БД/кэши, асинхронные паттерны и наблюдаемость P95/P99. Сфокусировавшись на хвостах и устранив «узкие горлышки», вы стабилизируете отклик, улучшите конверсию и снижаете стоимость миллисекунды — там, где это действительно влияет на бизнес.