Перейти к основному содержимому

Сеть для диагностики бэкенда

Разработчику

Play ITЗагрузка интерактивного демо…

Пользователь жалуется: "сайт тормозит". Часть причин — не в SQL и не в алгоритме, а в пути пакета от клиента до сервера и обратно. Бэкенд-разработчик должен отличать медленный код от медленной сети.

База: сеть и интернет, HTTP.


Практический фокус статьи

Эта статья помогает отвечать на рабочий вопрос "где узкое место":

  • в коде приложения;
  • в базе данных;
  • в сетевом маршруте между клиентом и API;
  • в прокси, CDN или TLS-слое.

Когда диагностика идёт по этой схеме, время до причины заметно сокращается.


Уровни, которые вас касаются

На каждом hop добавляется задержка. Время ответа API = обработка на сервере + сеть туда-обратно + очередь на балансировщике.

Эта формула задаёт правильную рамку анализа. Медленный ответ не указывает автоматически на проблемы кода: значимая доля времени может возникать до входа запроса в приложение.

Напоминалка по узлам цепочки

Балансировщик, CDN, кэш, API Gateway и rate limit — что делает каждый блок на схеме: 12 концепций распределённой архитектуры.

Под капотом DNS отвечает на порту 53, публичный API — на 443 (HTTPS), внутренняя БД — на 5432 / 3306 и т.д. — сводка по ролям в справочнике сетевых сервисов.


Ключевые метрики

МетрикаЧто означаетТипичный симптом
RTT (Round-Trip Time)Время туда-обратно до узлаВысокий RTT → долгий TTFB даже при лёгком коде
Latency / RTЗадержка доставки, время ответа запроса"Плавающее" время ответа
QPS / RPSЗапросов в секунду к APIОчереди, 503 при пике
ConcurrencyОдновременных активных запросовРост при том же QPS → запросы "зависают" дольше
JitterРазброс задержкиНестабильный UX, таймауты на мобильных сетях
Packet lossПотеря пакетовРетрансмиссии TCP, "зависания"
BandwidthПропускная способность каналаДолгая загрузка больших тел, не коротких API

Связь QPS, concurrency и среднего RT (QPS = Concurrency / Avg RT), а также отличие TPS от QPS — в масштабируемости и параллелизме.

TCP при потерях снижает скорость (контроль перегрузки). UDP (DNS, QUIC/HTTP3) ведёт себя иначе — потери могут проявляться как ошибки без повторной доставки на уровне приложения.

На практике это означает, что при одинаковой серверной нагрузке пользовательский опыт может заметно отличаться по регионам и типам сетей.


TCP и HTTP в двух словах

  • SYN → SYN-ACK → ACK — установление соединения (один RTT и больше).
  • Keep-Alive — повторное использование TCP для нескольких HTTP-запросов; без него каждый запрос платит handshake.
  • HTTP/2 — несколько запросов в одном TCP; снята очередь ответов HTTP/1.1, но при потере TCP-пакета могут встать все параллельные запросы в соединении.
  • HTTP/3 — те же запросы поверх QUIC (UDP) — потоки независимы, потеря пакета задерживает один запрос, подробнее в HTTP-интеграциях. Карта всего стека — HTTP-экосистема.
  • TLS — дополнительные RTT на handshake (смягчается session resumption).

Если API вызывается тысячи раз в секунду с коротким телом, оптимизация JSON может дать меньше, чем пул соединений к БД и keep-alive к upstream.


Симптом → гипотеза

НаблюдениеВероятная причинаЧто проверить
Медленно только из одного регионаМаршрут, CDN, гео-репликаТрассировка, DNS на региональный IP
Медленно только на мобильномВысокий RTT/джиттерПерцентили p95/p99, размер ответа
Таймауты пачкамиПотери, перегрузка LB, исчерпание портовМетрики LB, ss, лимиты
Быстро с сервера, медленно снаружиFirewall, NAT, неверный DNScurl с хоста vs с ноутбука
Быстро без TLS, медленно с TLSСертификат, цепочка, CPUПрофиль TLS, HTTP/2

Таблица помогает формировать инженерную гипотезу до глубокого анализа. Последовательность "симптом → проверка → следующая проверка" снижает хаотичные действия и ускоряет локализацию причины.


Инструменты разработчика

ИнструментНазначение
DevTools → NetworkВодопад запросов, TTFB, размер
curl -w (см. пример ниже)Время DNS/connect/TTFB с сервера
dig, hostЗаписи DNS, TTL, неверный A/AAAA
ping, traceroute / tracertRTT по хопам (ICMP может быть заблокирован)
Логи прокси (Nginx)$request_time, upstream time

Глубокий разбор пакетов (tcpdump, анализ в GUI) — задача инженера по эксплуатации; разработчику достаточно уметь заказать такой анализ с воспроизводимым request_id.

С сервера (или из CI на staging):

curl -s -o /dev/null -w \
"dns:%{time_namelookup}s connect:%{time_connect}s ttfb:%{time_starttransfer}s total:%{time_total}s code:%{http_code}\n" \
https://api.example.com/health

TTFB (Time To First Byte) в DevTools — время до первового байта ответа. В логах Nginx поле $request_time ближе к полной обработке на upstream. Если TTFB высокий, а $request_time низкий — ищите сеть/CDN; если оба высокие — бэкенд или БД.

Метрики на стороне страницы в браузере (FCP, DOM Content Loaded, вес страницы, блокирующие ресурсы) — в "Метрики производительности веб-страницы".


DNS — частый скрытый виновник

Каждый новый хост в цепочке микросервисов → резолвинг имени. Проблемы:

  • слишком большой TTL (Time To Live) записи DNS — после смены IP клиенты ещё долго ходят на старый адрес;
  • нет кэша резолвера в приложении;
  • IPv6 AAAA есть, но маршрут до IPv6 сломан (fallback замедляет).

Файл /etc/hosts на staging — легитимный способ подменить маршрут для отладки.


Разбор кейса "медленно после релиза"

Сценарий:

  • после релиза жалобы идут только из одного региона;
  • p95 вырос, p50 почти не изменился;
  • CPU и БД у сервиса остаются в норме.

Порядок проверки:

  1. Снять curl -w из проблемного региона и из дата-центра рядом с сервисом.
  2. Сверить DNS-ответы и TTL.
  3. Сравнить TTFB и полный total.
  4. Проверить логи балансировщика по $request_time и upstream latency.
  5. Сопоставить время деградации с изменениями в CDN/маршрутизации.

Этот шаблон хорошо показывает границу между "проблема кода" и "проблема доставки".

При повторяемом применении такой разбор превращается в командный runbook: новые инженеры быстрее входят в контекст, а инциденты закрываются на базе проверяемых фактов.


Что добавить в продовый API уже сейчас

  • Таймауты connect/read/write на каждый исходящий HTTP-вызов.
  • Retry с ограничением попыток и jitter для идемпотентных операций.
  • Явный request_id в запросах к downstream.
  • Метрики сетевых ошибок по классам — timeout, DNS, TLS, connection reset.
  • Дашборд с p50/p95/p99 отдельно по регионам и по мобильным/desktop клиентам.

Практические рекомендации для API

  1. Таймауты на исходящие вызовы (connect + read) — всегда явные.
  2. Идемпотентность и retry только на безопасных операциях — иначе дубли при ретрансмиссии TCP не спасут бизнес-логику.
  3. Сжатие (gzip, brotli) для крупных JSON — экономит bandwidth, тратит CPU.
  4. CDN для статики; API — ближе к пользователю через edge только если есть смысл (часто API остаётся в одном регионе).
  5. Смотрите p95/p99, не среднее — сеть "длинным хвостом" портит UX.

Связанные темы