Что такое сетевая задержка в Linux и из чего она состоит
Латентность (latency) - это время, которое пакет тратит на путь туда и обратно. Его называют RTT, round-trip time. Представь, что ты кричишь в ущелье и ждёшь эха: RTT - это пауза между криком и эхом. Чем дальше стенка, тем больше пауза. В сети "стенка" - это удалённый хост, а по дороге пакет проходит десятки промежуточных узлов (хопов): твой роутер, шлюз провайдера, магистральные маршрутизаторы, и так до цели.
Важно сразу разделить два разных явления:
- Задержка (latency) - пакеты доходят, но медленно. RTT большой.
- Потери (packet loss) - часть пакетов вообще не доходит. TCP их переотправляет, и из-за этого приложение встаёт колом.
Ещё разделяй, где возникает задержка. Локальная задержка - это когда тормозит сам хост: перегружен CPU, своп, диск не успевает, ядро не разгребает очереди пакетов. Сетевая задержка - это путь между хостами. Их легко перепутать: пользователь говорит "сеть тупит", а на деле приложение само по себе отвечает 800 мс, а сеть добавляет всего 3 мс. Поэтому диагностика латентности в Linux всегда идёт от простого к сложному: сначала доступность и RTT, потом путь по хопам, потом DNS, потом TCP-уровень конкретного соединения, потом интерфейс.

ping: доступность и RTT, и почему ping не вся правда
ping - первый инструмент. Он шлёт ICMP echo-request и ждёт echo-reply, замеряя RTT. По нему сразу видно три вещи: жив ли хост, какой RTT и есть ли потери.
Код: Выделить всё
ping -c 5 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=118 time=11.2 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=118 time=10.9 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=118 time=42.7 ms
64 bytes from 8.8.8.8: icmp_seq=5 ttl=118 time=11.0 ms
--- 8.8.8.8 ping statistics ---
5 packets transmitted, 4 received, 20% packet loss, time 4051ms
rtt min/avg/max/mdev = 10.9/18.9/42.7/13.6 msПолезные флаги (актуально на 2026): -i 0.2 - интервал между пробами (чаще; интервал меньше 0.2с без root режется), -D - метки времени перед строкой (видно, когда именно был скачок), -O - явно печатать строки про no answer для пропущенных проб, -M do -s 1472 - проверка MTU/фрагментации (запрет фрагментации, "do" = don't fragment): если такой пинг не проходит, а мелкий проходит - проблема в MTU на пути (частая причина "сайт открывается, но висит").
Что норма. Внутри одного дата-центра RTT обычно меньше 1 мс, до соседнего города - единицы мс, через полстраны - десятки мс, до другого континента - 100-300 мс. Любые устойчивые потери на проводной линии (не Wi-Fi) - уже повод копать.
Почему ping latency - не вся правда. Во-первых, ICMP многие маршрутизаторы обрабатывают по остаточному принципу или режут rate-limit'ом: хост может "пинговаться плохо", но реальный TCP-трафик через него летает. Во-вторых, ping проверяет только путь до хоста, но не до конкретного порта и не сам сервис: ICMP до веб-сервера зелёный, а на 443 он отдаёт 500-е по полминуты. Если нужна именно доступность порта и время установки TCP-сессии - бери tcp-пробу, например nc -vz host 443 с замером через time, или mtr в TCP-режиме (об этом ниже). В-третьих, ping не покажет, на каком из 15 хопов начались проблемы. Для этого нужен следующий инструмент.
mtr и traceroute: где именно по пути растёт задержка
traceroute показывает маршрут - список хопов от тебя до цели, с RTT на каждом. Он постепенно увеличивает TTL пакета, и каждый хоп, "убивший" пакет по TTL, отвечает ICMP Time Exceeded - так мы видим всю цепочку. Но traceroute шлёт мало проб и даёт мгновенный снимок. mtr (My TraceRoute) - это traceroute и ping в одном: он непрерывно гоняет пробы по всем хопам и копит статистику в реальном времени. Для поиска плавающих потерь mtr linux - первый выбор.
Код: Выделить всё
sudo mtr -rwzbc 50 cyberlake.ruКод: Выделить всё
HOST: myhost Loss% Snt Last Avg Best Wrst StDev
1. 192.168.1.1 0.0% 50 0.4 0.5 0.3 1.2 0.1
2. 10.0.0.1 0.0% 50 3.1 3.4 2.9 9.8 0.9
3. core-router.isp.net 0.0% 50 12.0 12.3 11.8 18.0 1.1
4. ??? 100.0% 50 0.0 0.0 0.0 0.0 0.0
5. peer.backbone.net 24.0% 50 88.0 91.2 85.0 240.0 31.4
6. cyberlake.ru 2.0% 50 89.0 90.1 86.0 130.0 8.2Главная ловушка чтения mtr - "транзитные потери". Хоп 4 показывает 100% Loss, но это не обрыв. Многие маршрутизаторы намеренно не отвечают на TTL-просроченные пакеты (control-plane rate-limit на генерацию ICMP), но при этом нормально пересылают транзитный трафик дальше. Доказательство - хопы 5 и 6 после него отвечают. Правило (подтверждается практикой провайдеров): если следующий хоп показывает Loss 0% - то, что было выше, это rate-limit, а не реальная потеря. Реальная проблема там, где потери появляются и держатся до самого последнего хопа. Здесь на хопе 5 - 24%, но на финальном хопе 6 - всего 2%, значит на 5 это был тоже преимущественно rate-limit, а вот настоящие 2% loss на цели - это уже реальная (хоть и небольшая) потеря до сервера.
По задержке логика та же: смотри, на каком хопе Avg скакнул и больше не вернулся к низким значениям. Здесь скачок с 12 до 88 мс между хопом 3 и 5 - вот где растёт задержка, это стык провайдера с магистралью (по ASN из -z видно, чей это узел). Высокий StDev на хопе 5 (31.4) - сигнал перегруженного или нестабильного стыка. И ещё: высокий RTT на промежуточном хопе при низком RTT на следующем - норма. Это значит лишь, что данный конкретный роутер медленно отвечает своим control-plane на ICMP, а транзит у него быстрый. Ориентируйся на тренд RTT, а не на отдельный "красный" хоп в середине.
DNS как скрытый источник тормозов
Очень частая история: "сеть медленная", а на деле тупит резолвинг имён. Каждое подключение по имени сперва идёт в DNS, и если резолвер отвечает за секунду - вот тебе и "лаги". Проверяем явно.
Код: Выделить всё
dig cyberlake.ru
;; Query time: 312 msec
;; SERVER: 127.0.0.53#53(127.0.0.53)
;; WHEN: ...Проверь и системный путь резолвинга (он учитывает /etc/hosts, nsswitch, кэш systemd-resolved):
Код: Выделить всё
time getent hosts cyberlake.ru
real 0m0.004sss -ti: задержки и ретрансмиты на уровне TCP
ping и mtr меряют ICMP. Но твоё приложение работает по TCP, и у каждого соединения ядро считает собственный RTT и переотправки. ss -ti достаёт эту внутреннюю кухню прямо из ядра - это лучший способ понять, тормозит ли конкретное соединение из-за сети. (Заодно запомни: netstat устарел, в 2026 стандарт - именно ss из iproute2.)
Код: Выделить всё
ss -ti
ESTAB 0 0 10.0.0.5:54312 93.184.216.34:443
cubic wscale:7,7 rto:296 rtt:92.4/8.1 mss:1448 cwnd:10 ssthresh:7
bytes_sent:284211 bytes_acked:279139 bytes_retrans:5072
segs_out:421 segs_in:198 retrans:0/6 rcv_rtt:94
delivery_rate:1.2Mbps pacing_rate:2.4MbpsВывод по интерпретации: высокий rtt + ненулевой retrans/растущий bytes_retrans = проблема в сети или у удалённого хоста. rtt маленький, retrans нулевой, delivery_rate нормальный, а приложение всё равно тормозит = виновата не сеть, копай сам сервис (CPU, блокировки, диск, GC, медленный backend). Чтобы не глазеть на одно соединение, отсортируй проблемные: ss -tin state established '( dport = :443 )' и грепай по retrans.
ip -s link: ошибки и дропы на сетевом интерфейсе
Если потери есть, проверь, не теряет ли пакеты сам интерфейс - до всякой сети. Это локальный уровень: перегруженная карта, переполненные очереди, битый кабель.
Код: Выделить всё
ip -s link show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ...
RX: bytes packets errors dropped missed mcast
9823746512 8451233 0 1840 0 1204
TX: bytes packets errors dropped carrier collsns
4521098233 6120987 0 0 0 0На современных дистрибутивах (включая Astra Linux и RED OS - тоже systemd-based) всё это работает идентично: ip и ss из пакета iproute2, mtr ставится из репозитория (mtr или mtr-tiny). Если нужна сводка "трафик плюс ошибки по интерфейсам одной таблицей" - удобны sar -n DEV,EDEV (из sysstat) или nstat; они показывают приросты счётчиков, а не абсолют, что нагляднее.
eBPF в 2026: следующий шаг диагностики латентности
ss даёт срез "сейчас", а где именно в стеке съедается время - нет. В 2026 это закрывают eBPF-инструменты: они вешаются на события ядра с почти нулевым оверхедом и не требуют перехвата всего трафика, как tcpdump. Нужен относительно свежий ядро с поддержкой BTF/CO-RE (массово доступно), и пакеты bpfcc-tools (bcc) и bpftrace.
- tcprtt-bpfcc - гистограмма RTT по TCP в реальном времени. Видно не среднее, а распределение: где хвост латентности (p99), а не только норма.
- tcpretrans-bpfcc - печатает каждый факт ретрансмита: какие IP:порт и в каком состоянии TCP. Идеально, чтобы поймать, какое именно соединение и куда теряет пакеты.
- tcpdrop-bpfcc - показывает, где ядро дропает пакеты, со стеком вызовов: бесценно, когда дропы есть, а причина неочевидна.
- netstacklat (новый инструмент 2026 от сообщества eBPF) - измеряет задержку прохождения пакета внутри сетевого стека ядра, отделяя "тормозит сеть" от "тормозит обработка на хосте".
Код: Выделить всё
sudo tcpretrans-bpfcc
TIME PID IP LADDR:LPORT T> RADDR:RPORT STATE
10:24:01 0 4 10.0.0.5:54312 R> 93.184.216.34:443 ESTABLISHEDТипичные грабли и заблуждения
- "Хоп в mtr показывает 100% потерь - значит обрыв". Нет. Если следующий хоп отвечает 0% - это rate-limit ICMP, транзит идёт. Смотри потери, которые держатся до последнего хопа.
- "Высокий RTT на среднем хопе - там проблема". Не обязательно. Если на следующем хопе RTT снова низкий - это просто медленный control-plane роутера. Ориентируйся на тренд до цели.
- "Пинг хороший - значит сеть ок". ICMP и TCP по-разному приоритезируются и фильтруются. Проверяй TCP через ss -ti, mtr -T и реальный сервис, а не только ping.
- Путаница локальной и сетевой задержки. Если ss-rtt маленький, retrans нулевой, delivery_rate нормальный, а медленно - виновата не сеть, а приложение/хост.
- Забывают про DNS. Полсекунды на резолв воспринимают как "сеть тормозит". Меряй time getent и dig Query time, проверяй @8.8.8.8 напрямую.
- Wi-Fi и потери. На беспроводе потери и скачки RTT - норма жизни; делай выводы о "сети" только на проводном линке или с поправкой на радио.
- MTU/фрагментация. Соединение устанавливается, но виснет на больших ответах - проверь ping -M do -s ...; это не "потери", а резка крупных пакетов на пути.
- ping -c 20 до своего шлюза и до 8.8.8.8. Сравни RTT и mdev, посмотри percent loss и пропуски icmp_seq.
- sudo mtr -rwzbc 30 до любимого сайта, затем sudo mtr -T -P 443 туда же. Найди хоп, где впервые вырос Avg и больше не упал. Отличи транзитные 100% (следующий хоп 0%) от реальных потерь до последнего хопа.
- dig домен и dig @8.8.8.8 домен и time getent hosts домен. Сравни Query time с реальным RTT из ping - DNS быстрее или медленнее сети?
- Открой ss -ti, найди живое соединение (ssh или к базе), прочитай rtt, retrans, bytes_retrans, delivery_rate. Сними два замера и посчитай дельту bytes_retrans - идут ли потери сейчас?
- ip -s link show на основном интерфейсе. Проверь RX/TX errors, dropped, missed/carrier - есть ли что-то кроме нулей. Если есть - загляни в ethtool -S.
- Если доступны bpfcc-tools: запусти sudo tcpretrans-bpfcc на минуту под нагрузкой - увидишь живой поток ретрансмитов.
- Чем потери пакетов отличаются от высокой задержки и почему даже 1-2 процента loss бьют по TCP сильнее, чем рост RTT?
- В mtr хоп посередине показывает 100% Loss, а следующий за ним - 0%. Где проблема и почему?
- Какие поля ss -ti укажут, что соединение страдает именно от потерь, а не от приложения, и как понять, идут ли потери прямо сейчас?
- Как за минуту проверить, что виноват DNS, а не "медленная сеть"?
Диагностика латентности идёт лесенкой: ping - есть ли вообще RTT и потери; traceroute/mtr - на каком хопе пути растёт задержка или начинаются потери (и держатся ли они до конца, не rate-limit ли это); dig и time getent - не тормозит ли DNS; ss -ti - реальный RTT, ретрансмиты и delivery_rate конкретного TCP-соединения; ip -s link и ethtool -S - ошибки и дропы на самом интерфейсе; eBPF (tcprtt, tcpretrans, tcpdrop, netstacklat) - хвосты латентности и точное место дропа в ядре. Главный навык - различать, где медленно: приложение, хост или сеть. ping показывает доступность, mtr показывает путь, ss -ti показывает правду на уровне TCP, ip -s link ловит локальные дропы, а eBPF в 2026 добивает то, что раньше требовало strace и tcpdump. Не доверяй одной команде - смотри связку.