Давайте дружить в Телеграме: рассказываем про новые фичи и общаемся в комментах Подписаться
support@serv.host
Личный кабинет

Почему пинг ничего не говорит: jitter, потери пакетов и bufferbloat

Почему пинг ничего не говорит: jitter, потери пакетов и bufferbloat

Вообще я микроразработчик, со мной можно связаться как угодно, я открыт ко всему

Сторонний мой проект: Zapret2UI.


ping 12 ms. Отлично же, канал шикарный.

А потом созвон рассыпается на слоги, в игре персонаж телепортируется, страницы то грузятся мгновенно, то думают по три секунды. Идёте проверять - ping всё те же 12 мс. Идёте на спидтест - 300 Мбит. По всем приборам здорово, по факту пользоваться невозможно.

Так вот, ping не сломан. Он честно показывает ровно одну цифру, а вам нужны три другие. И самое обидное - та единственная цифра, которую он показывает, для половины реальных задач вообще не главная.

Разберём, что там на самом деле происходит: почему средний пинг скрывает всё интересное, почему ICMP - это в принципе не ваш трафик, откуда берётся jitter и как он превращается в рваный звук, почему один процент потерь роняет гигабитный канал до полутора мегабит, и что такое bufferbloat - беда, которую породили из лучших побуждений.

Кому пригодится: если выбираете хостера и смотрите только на пинг из своего города; если сервис «то работает, то нет», а метрики зелёные; или если хочется наконец понять, что показывает mtr и почему там красное на середине пути.

Половина команд ниже пересекается с чеклистом по проверке VPS - там про то, что вам дали по железу, а тут про то, что дали по сети.


Содержание

  1. Что на самом деле меряет ping
  2. ICMP это не ваш трафик
  3. Jitter: почему рассыпается голос
  4. Один процент потерь и мёртвый гигабит
  5. Bufferbloat: беда от лишней памяти
  6. Как читать mtr и не паниковать
  7. Чем мерить по-настоящему
  8. Что чинится, а что нет
  9. Какая метрика под какую задачу
  10. Частые ошибки
  11. Где это проверять
  12. Короткий итог

Источники


Что на самом деле меряет ping

Утилита отправляет ICMP Echo Request, ждёт Echo Reply, засекает время. Получается RTT - время туда и обратно. Одно число, усреднённое по десятку пакетов.

Смотрим на типичный вывод внимательнее, чем обычно:

--- 1.1.1.1 ping statistics ---
100 packets transmitted, 100 received, 0% packet loss, time 20147ms
rtt min/avg/max/mdev = 11.2/14.8/197.4/21.3 ms

Все смотрят на avg - 14,8 мс, красота. А теперь гляньте на max: 197 мс. Какой-то пакет ехал в тринадцать раз дольше средней. Средняя это проглотила и не поперхнулась, потому что среднее так и работает: девяносто девять хороших замеров прячут один плохой.

Для скачивания файла такой выброс не значит ничего. Для голосового звонка это щелчок в ухе.

mdev - самое полезное поле, и самое игнорируемое. Формально «среднее отклонение», по факту iputils считает там обычное стандартное отклонение RTT. То есть насколько замеры разбросаны вокруг средней. Вот это уже близко к тому, что называют jitter'ом, хотя строго говоря не он (настоящий jitter по RFC 3550 считается по-другому - как сглаженное среднее разниц между соседними пакетами, а не как разброс вокруг центра). Для бытовой диагностики разница несущественная: если mdev заметно больше нуля, канал дёргается.

Четыре вещи, которые ping не покажет никогда

Он не различает направления. RTT - это сумма. 100 мс могут быть двадцатью туда и восьмьюдесятью обратно, и это не редкость: маршруты в интернете асимметричны по умолчанию, обратный путь почти всегда идёт не через те же роутеры. А чинить надо тот, который тормозит. По RTT вы не поймёте какой.

Он врёт про ваш собственный Wi-Fi. Беспроводная сеть добавляет свой разброс: повторы, коллизии, смена скорости на лету, энергосбережение на ноутбуке. Меряете пинг до сервера по вайфаю и половину результата приносите из соседней комнаты. Меряйте по проводу, иначе диагностируете свой роутер, а думаете, что диагностируете хостера.

Он молчит про поведение под нагрузкой. Пустой канал отвечает за 12 мс. Начали качать - и стало 800. Обычный ping в простое этого не увидит вообще, а именно это состояние вы и ощущаете как «интернет тупит».

Десять пакетов - не статистика. Дефолтный ping на винде шлёт четыре пакета, на линуксе гоняет до Ctrl+C, но обычно люди смотрят секунд пять. А те проблемы, которые и портят жизнь, вылезают раз в минуту. Гоняйте так:

ping -c 300 -i 0.2 1.1.1.1

Триста пакетов с интервалом в 200 мс, минута работы. И смотреть надо на max и mdev, а не на avg.


ICMP это не ваш трафик

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

Причина первая: роутеры ICMP не любят. Когда пакет просто проезжает через маршрутизатор, его обрабатывает специализированное железо на полной скорости порта. А когда роутеру надо самому ответить (на ping или на traceroute-зонд с истёкшим TTL) - это работа для процессора управляющей платы. Процессор там слабенький, и защищать его надо, иначе любой школьник положит железку одним скриптом. Поэтому на всех нормальных роутерах стоит ограничение: отвечаю на столько-то ICMP в секунду, остальное молча выкидываю.

В линуксе, кстати, это видно прямо в sysctl:

sysctl net.ipv4.icmp_ratelimit
# net.ipv4.icmp_ratelimit = 1000

Значение в миллисекундах: минимальный интервал между ответами определённых типов. Ваш сервер тоже так делает, просто вы об этом не думали.

Итог: потери в ping'е могут означать «роутер поленился ответить», а транзитный трафик через него в это время шёл без единой потери на полной скорости.

Причина вторая: провайдеры режут ICMP как класс. Не со зла, а потому что он не приносит денег и его удобно душить первым при перегрузке. Некоторые вообще ставят ему низший приоритет в очередях. Ваш пинг деградирует первым, хотя реальный трафик ещё в порядке. Бывает и наоборот: у хостера ICMP пролетает шикарно, а TCP-сессии рвутся.

Причина третья, самая недооценённая: вы едете не по тому проводу. Между крупными точками сети обычно не один линк, а несколько параллельных, и трафик по ним раскидывают через ECMP - хешируют пятёрку из адреса отправителя, адреса получателя, протокола и двух портов, и по хешу выбирают линк. Это нужно, чтобы пакеты одного соединения не переставлялись местами.

Только у ICMP портов нет. Вообще. Значит, и хеш у него считается по другим данным, значит, и линк ему достанется другой. Ваш ping едет по волокну номер три, а ваш HTTPS на 443-й порт - по волокну номер семь. Третье свободно, седьмое забито. Пинг прекрасен, сайт не грузится, и оба измерения честные.

Практический вывод. Хотите узнать, как себя чувствует ваш трафик - меряйте тем же протоколом, каким ходите:

# TCP-режим mtr, зонды идут SYN-пакетами на 443
mtr -T -P 443 -rwzbc 200 example.com

# то же самое через hping3
hping3 -S -p 443 -c 20 example.com

Разница между mtr и mtr -T -P 443 до одного и того же адреса иногда шокирует. Если ICMP-вариант показывает 3% потерь, а TCP-вариант ноль - никаких потерь у вас нет, вам просто не отвечали.

Это же, кстати, причина не ставить в мониторинге проверку типа Ping и на том успокаиваться - подробнее в статье про свой мониторинг.


Jitter: почему рассыпается голос

Jitter - разброс задержки. Не сама задержка, а то, насколько она скачет от пакета к пакету.

И вот тут контринтуитивная вещь, которую надо принять: стабильные 80 мс лучше, чем скачущие от 20 до 200. Даже если во втором случае бывает вдвое быстрее. Для всего реального времени - голос, видео, игры - предсказуемость важнее скорости.

Механизм: буфер джиттера

Голос по сети едет мелкими пакетами, обычно по 20 мс звука в каждом. Отправитель шлёт их идеально ровно, через равные промежутки. Сеть эту ровность разрушает: один пакет постоял в очереди, второй проскочил, третий поехал другим маршрутом.

На приёмной стороне поток надо собрать обратно в ровный, иначе звук будет ускоряться и замедляться. Для этого стоит jitter buffer: приёмник придерживает пакеты, копит запас, скажем, на 50 мс, и отдаёт их декодеру равномерно.

Дальше самое интересное. Пакет, который опоздал сильнее, чем глубина буфера, - выбрасывается. Не потому, что сеть его потеряла, - сеть его честно доставила. Просто он приехал, когда этот кусочек звука уже прозвучал, и он больше не нужен.

Получается, jitter превращается в потери на уровне приложения, даже когда в сети потерь ноль. Вы смотрите на статистику канала, там 0% packet loss, а собеседник слышит вас пунктиром.

Умные буферы подстраиваются: видят разброс - увеличивают глубину. Меньше выброшенных пакетов, но растёт задержка, и разговор превращается в переговоры по рации с паузами и «алло, ты меня слышишь?». Выбор всегда один и тот же: либо рвётся, либо тормозит.

Сколько это в цифрах

Тут есть настоящий ориентир, а не выдуманный. В рекомендации ITU-T G.114 давно расписаны пороги по односторонней задержке: до 150 мс большинство людей не замечает вообще, 150-400 мс уже чувствуется, но разговаривать можно, выше 400 мс - разговор ломается, собеседники начинают перебивать друг друга.

Обратите внимание: односторонней. То есть примерно половина того RTT, который вам показывает ping. Гоняете голос через сервер с пингом 250 мс - у вас 125 мс в одну сторону только на сеть, плюс кодирование, плюс буфер, плюс декодирование. Бюджет съеден.

Про сам разброс жёсткого стандарта нет, но по практике: mdev в пределах единиц миллисекунд - канал ровный, десятки - уже слышно, сотни - можно не звонить.

Откуда берётся

  • Очереди на перегруженном участке. Основной источник. Пакет ждёт своей очереди столько, сколько занято впереди, а занятость всё время меняется.
  • Wi-Fi. Само по себе. Общая среда, коллизии, повторные передачи, адаптация скорости, засыпающий радиомодуль ради экономии батареи.
  • Мобильная сеть. Там задержка вообще живёт своей жизнью, особенно при переключении между сотами.
  • Bufferbloat. Об этом дальше отдельно, он даёт самый зрелищный разброс.

Один процент потерь и мёртвый гигабит

«Ну потерялся один пакет из ста, невелика беда, TCP же перешлёт». Перешлёт. Только сначала он сделает вывод.

TCP в классических реализациях (Reno, CUBIC, который стоит по умолчанию в линуксе) считает потерю пакета сигналом перегрузки. Логика родом из восьмидесятых и вполне здравая: провода не теряют пакеты просто так, теряют переполненные очереди, значит сеть перегружена, значит надо сбавить. И отправитель режет окно, а потом медленно наращивает обратно.

Пока потери случайные и редкие - механизм работает. Когда потери идут постоянно, окно не успевает вырасти между просадками, и скорость встаёт колом. Причём встаёт независимо от ширины канала.

Считается это формулой Матиса. Верхняя граница для одного TCP-потока получается примерно такая: размер сегмента, делённый на RTT, умноженный на константу и делённый на корень из вероятности потери. Подставим реальные числа (сегмент 1460 байт):

ПотериRTT 20 мсRTT 100 мс
0,01%~71 Мбит/с~14 Мбит/с
0,1%~22 Мбит/с~4,5 Мбит/с
1%~7 Мбит/с~1,4 Мбит/с

Прочитайте правый нижний угол ещё раз. Один процент потерь на канале с пингом 100 мс - и одно TCP-соединение не разгонится выше полутора мегабит. Хоть у вас десятигигабитный порт, хоть сто. Ширина канала в формуле не участвует вообще.

Вот почему «у меня же гигабит, почему файл качается со скоростью модема» - вопрос не про гигабит.

Отсюда растёт куча знакомых странностей

Спидтест показывает норму, а скачивание ползёт. Спидтесты качают в несколько потоков одновременно. Каждый поток по отдельности страдает от потерь, но их десять, и в сумме получается прилично. Одиночная закачка через curl - это один поток, и он получает свои полтора мегабита. Ровно этот эффект вы видите, когда iperf3 -P 8 из чеклиста по проверке VPS даёт совсем не то, что iperf3 в один поток.

Браузер шустрее, чем консольная утилита. По той же причине: он открывает несколько соединений и тянет ресурсы параллельно.

Помогает смена congestion control. BBR не использует потери как основной сигнал перегрузки, он строит модель канала по измеренной полосе и минимальному RTT. На линии с фоновыми потерями разница бывает в разы, и именно поэтому его так любят вкручивать в прокси-конфиги. Правда, включается он не в конфиге прокси, а в ядре (net.ipv4.tcp_congestion_control), и если модуль не загружен, строчка в конфиге не значит ничего - я про это писал подробно в разборе конфигов Xray. Ещё BBR довольно нагло ведёт себя по отношению к соседним потокам, так что серебряной пулей его считать не стоит.

Не все потери одинаковы

Для скорости важен процент. Для голоса и игр важнее как они распределены.

Один процент, размазанный ровно по всему потоку, современный голосовой кодек замаскирует так, что вы не заметите: он достроит недостающий кусочек по соседним. А вот тот же один процент, прилетевший пачкой из пяти пакетов подряд, - это сто миллисекунд тишины, которую ничем не замаскируешь. Такие пачки как раз и дают роутеры, когда переполняется очередь: они выкидывают не по одному, а всё, что не влезло, разом.

Отдельная категория для российских реалий

Потери бывают не сетевыми. Если соединение стабильно рвётся на определённых сайтах, на определённом порту или строго после начала передачи данных, а до соседнего сервера в том же дата-центре всё летает - это уже не про качество канала. Отличить такое легко: настоящие сетевые потери не разбирают, куда вы идёте, и бьют одинаково по всем адресам за проблемным участком. Избирательность - признак того, что кто-то смотрит внутрь.


Bufferbloat: беда от лишней памяти

Моя любимая история в сетях, потому что она про то, как хорошее намерение всё сломало.

Память дешевела, и производители сетевого железа рассуждали логично: чем больше буфер, тем меньше пакетов придётся выбросить при всплеске нагрузки. Потери - это плохо, значит, буферы делаем побольше. И набили их в модемы, роутеры, базовые станции, драйверы сетевых карт.

Проблема в том, что TCP узнаёт о перегрузке из потерь. Это его единственный надёжный сигнал.

Смотрите, что получается. Канал забился, но пакеты не выбрасываются - они выстраиваются в очередь. Отправитель потерь не видит, делает вывод, что всё отлично, и разгоняется дальше. Очередь растёт. Отправитель разгоняется ещё. Очередь растёт ещё.

К тому моменту, когда сигнал о перегрузке всё-таки дойдёт, в буфере уже лежат секунды трафика. И каждый пакет теперь проходит через эту очередь. Ваш DNS-запрос, ваш ping, ваш пакет с голосом - все послушно встают в хвост за тремя мегабайтами торрента.

Вот классическая картина, которую видел каждый, но мало кто знал, как она называется:

в простое:          ping 15 мс
началась закачка:   ping 780 мс

Никаких потерь, никаких ошибок. Просто интернет превратился в кисель, пока что-то качается. Буферы, которые ставили ради борьбы с потерями, обменяли потери на задержку - причём по грабительскому курсу.

Почему это не видно обычными тестами

Спидтест меряет полосу. Полоса при bufferbloat отличная, буфер же её и обеспечивает. Ping в простое тоже отличный, очереди пустые.

Мерить надо задержку под нагрузкой - latency under load. То есть одновременно грузить канал и пинговать. Ровно это и делают специальные тесты вроде Waveform или LibreQoS: сначала замер в покое, потом заливка вниз с параллельным замером, потом заливка вверх, и на выходе оценка буквой от A+ до F. Первый раз это стоит прогнать просто из любопытства, результат обычно бодрит.

Руками то же самое делается в два окна:

# окно 1
ping -i 0.2 1.1.1.1

# окно 2 - грузим канал на 30 секунд
iperf3 -c <сервер> -t 30 -P 4

Смотрите, что происходит с пингом в первом окне в момент старта заливки. Вырос в десять раз - у вас bufferbloat.

Лечение: AQM

Идея активного управления очередью в том, чтобы начинать отбрасывать пакеты до того, как очередь распухнет. Не когда буфер полон, а когда пакеты начали в нём залёживаться.

CoDel (RFC 8289) зашёл с неожиданной стороны: он следит не за длиной очереди, а за временем, которое пакет в ней проводит. Логика в том, что длина очереди сама по себе ни о чём не говорит - короткий всплеск - это нормально, плохо, когда очередь не рассасывается. Как только время ожидания стабильно превышает целевое (по умолчанию 5 мс), CoDel начинает подкидывать дропы, и отправитель получает свой сигнал притормозить.

FQ-CoDel (RFC 8290) добавил сверху справедливое разделение по потокам. Каждый поток получает свою очередь, и торрент в сорок соединений физически не может отодвинуть ваш единственный пакет с голосом в конец. Это и есть та штука, из-за которой на нормально настроенном роутере зум не замечает, что рядом качается образ убунты.

CAKE - развитие идеи, всё в одном флаконе: шейпер, честное разделение, приоритизация, учёт накладных расходов канала. В ядре Linux с версии 4.19.

На сервере проверяется одной командой:

sysctl net.core.default_qdisc
tc qdisc show dev eth0

Хорошая новость: на современных дистрибутивах с systemd там, скорее всего, уже стоит fq_codel - systemd прописывает его в своих дефолтных sysctl'ах ещё с 2014 года, специально ради борьбы с bufferbloat. Так что если увидите древний pfifo_fast - либо система очень старая, либо кто-то это переопределил руками.

Меняется так:

# разово
tc qdisc replace dev eth0 root fq_codel

# насовсем
echo 'net.core.default_qdisc = fq_codel' | sudo tee /etc/sysctl.d/99-aqm.conf
sudo sysctl --system

Честная оговорка про то, где это работает

Очередь на вашем сервере управляет только исходящим трафиком с этого сервера. Если бутылочное горлышко находится у провайдера или на магистрали - вы этой очередью не управляете и сделать с ней ничего не можете. Никакой qdisc на VPS не починит перегруженный пиринг.

На домашнем роутере смысла больше, но там есть свой фокус: чтобы AQM работал, очередь должна образоваться у вас, а не у провайдера. Поэтому в настройках SQM скорость шейпера ставят на 85-95% от реальной - вы намеренно немного жертвуете полосой, зато узкое место переезжает на ваше устройство, где вы им распоряжаетесь. Отдать несколько процентов скорости в обмен на то, что задержка под нагрузкой не улетает в небо, - обмен более чем выгодный.

Куда всё это движется

Современное продолжение темы - L4S (RFC 9330). Идея в том, чтобы вообще перестать использовать потери как сигнал: сеть помечает пакеты специальным флагом ECN задолго до того, как очередь станет проблемой, а отправитель на это реагирует. Плюс две отдельные очереди, чтобы новый механизм не конфликтовал со старым. Дело уже не чисто теоретическое: оператор T-Mobile в США раскатал L4S по своей 5G-сети. До массовых домашних провайдеров дойдёт нескоро, но направление задано.


Как читать mtr и не паниковать

mtr - это traceroute и ping в одном флаконе: гоняет зонды непрерывно и показывает статистику по каждому хопу. Инструмент отличный, но читают его неправильно примерно все, и в поддержку хостеров ежедневно летят скриншоты с паникой на пустом месте.

Типичный вывод:

HOST                          Loss%   Snt   Last   Avg  Best  Wrst StDev
1. 192.168.1.1                 0.0%   200    0.4   0.5   0.3   1.2   0.1
2. 10.20.0.1                   0.0%   200    2.1   2.4   1.9   8.7   0.6
3. core1.isp.net              14.5%   200    3.8   4.1   3.2  12.4   0.9
4. border.isp.net              0.0%   200    5.2   5.5   4.8  15.1   1.1
5. ix-peering.net              0.0%   200   18.3  18.9  17.9  28.2   1.3
6. target.example.com          0.0%   200   19.1  19.6  18.8  31.5   1.5

Третий хоп горит красным - 14,5% потерь. Вроде найден виновник, можно писать гневное письмо.

Не надо. Смотрите на строчку ниже: там ноль.

Разгадка в том, о чём мы говорили выше. Чтобы показаться в трассировке, роутер должен сам сгенерировать ICMP-ответ - а это работа для его управляющего процессора, и он её ограничивает. Транзитный трафик при этом идёт через ту же железку в полном порядке, потому что его обрабатывает совсем другой тракт. Роутер не потерял ваши пакеты, он поленился ответить на зонды.

Правило чтения ровно одно: потери реальны, только если они начинаются на каком-то хопе и держатся до самого конца. Пропали на следующей строке - забудьте, это ограничение ICMP, а не проблема сети.

И наоборот, вот такая картина - настоящая беда:

3. core1.isp.net               6.2%   200    3.8   4.1   3.2  12.4   0.9
4. border.isp.net              6.5%   200    5.2   5.5   4.8  15.1   1.1
5. ix-peering.net              6.1%   200   18.3  18.9  17.9  28.2   1.3
6. target.example.com          6.4%   200   19.1  19.6  18.8  31.5   1.5

Потери появились на третьем хопе и дошли до конца примерно теми же процентами. Вот теперь виноват третий, и вот с этим уже можно идти в поддержку.

Последняя строка вообще самая главная. Если на ней ноль - у вас всё хорошо, что бы ни творилось выше.

Второй момент, про который забывают: трасса односторонняя

mtr видит только путь от вас к цели. Обратный путь может идти вообще через другие страны, и если проблема там - в вашей трассировке она не отобразится никак. Вы будете смотреть на идеальный вывод и не понимать, почему всё плохо.

Поэтому правило обращения в поддержку: прикладывать два отчёта - свой до сервера и встречный, снятый на сервере до вашего адреса. Одностороннюю трассу поддержка первым делом попросит дополнить, так что сэкономьте себе круг переписки.

# у себя
mtr -rwzbc 200 <IP-сервера> > mtr-to-server.txt

# на сервере (ваш публичный адрес узнаётся через curl ifconfig.me)
mtr -rwzbc 200 <ваш-IP> > mtr-from-server.txt

Флаги: -r отчёт вместо интерактива, -w широкий вывод с полными именами, -z показывать номера автономных систем (сразу видно, где кончается один оператор и начинается другой), -b показывать и имя, и адрес, -c 200 сколько зондов гонять.


Чем мерить по-настоящему

Собрал в кучу то, чем реально пользуюсь.

Разброс задержки, без затей:

ping -c 300 -i 0.2 <цель>

Триста пакетов, минута. Смотрим mdev и max, на avg не ведёмся.

Тем протоколом, которым ходим:

mtr -T -P 443 -rwzbc 200 <цель>

Если ICMP-версия показывает потери, а эта нет - потерь нет.

Честный jitter и потери разом. UDP-режим iperf3 для этого и сделан: он шлёт с заданной скоростью и на приёмнике считает и разброс, и сколько датаграмм не доехало.

iperf3 -c <сервер> -u -b 50M -t 30

В отчёте будут колонки Jitter и Lost/Total. Это самый прямой ответ на вопрос «что там с каналом», какой можно получить за тридцать секунд.

Односторонняя задержка. Самая простая утилита для этого - irtt. Нужен свой сервер на другой стороне, зато вы наконец увидите, какое направление тормозит:

# на сервере
irtt server

# у себя
irtt client -i 20ms -d 30s <сервер>

Bufferbloat. Браузерные тесты latency under load (Waveform, LibreQoS) дают оценку буквой за две минуты. Руками - ping в одном окне и iperf3 в другом, как выше.

Быстрая общая картина. speed.cloudflare.com кроме скорости показывает задержку под нагрузкой, разброс и потери. Для «глянуть одним глазом» удобнее всего.

Что за очередь стоит:

tc qdisc show dev eth0

Из-под винды: pathping (встроенный, совмещает трассировку со статистикой потерь, только долго думает) и psping из Sysinternals - он умеет TCP-режим, то есть обходит проблему деприоритезации ICMP.

Два правила замера, без которых всё бессмысленно

Мерьте по проводу. Wi-Fi добавляет свой разброс, и вы не отличите его от сетевого. Хотите проверить хостера - воткните кабель.

Мерьте в разное время суток. Перегруженный пиринг живёт по расписанию: днём всё летает, вечером всё встаёт. Один замер в три часа дня не значит ничего - ровно та же история, что и с оверселлом железа.


Что чинится, а что нет

Честное разделение, потому что половину проблем с сетью чинить бесполезно, и лучше знать об этом заранее.

Чинится вами:

  • Домашний роутер и его буферы. SQM с fq_codel или CAKE, шейпер на 90% реальной скорости. Часто это вообще единственная реальная проблема, а грешат на провайдера.
  • Wi-Fi. Провод, смена канала, разнос точек. Скучно, но работает.
  • Очередь на исходящем интерфейсе вашего VPS - fq_codel, одна строчка в sysctl.
  • Алгоритм контроля перегрузки на вашем сервере. BBR вместо CUBIC там, где линия с фоновыми потерями.
  • MTU и фрагментация. Отдельная классика: где-то по пути MTU меньше вашего, а ICMP с сообщением об этом отфильтрован, и в результате мелкие пакеты ходят, а крупные исчезают. Выглядит как мистика («ping идёт, сайт не грузится»), лечится подбором MTU.

Не чинится вами никак:

  • Перегруженный стык между вашим провайдером и хостером. Хоть обнастраивайтесь.
  • Потери в магистрали.
  • Кривая оптика на промежуточном участке.
  • Асимметричный маршрут, где обратный путь идёт через полмира.

Единственное лекарство от второй группы - сменить маршрут. То есть другая локация дата-центра, другой хостер, другой аплинк. Иногда переезд сервера из одного города в другой у того же провайдера чинит всё, потому что трафик поехал через другой стык.

Именно поэтому при выборе хостера пинг из вашего города - метрика более полезная, чем характеристики железа. Железо у всех примерно одинаковое, а вот маршруты до вашего провайдера у всех разные.


Какая метрика под какую задачу

ЗадачаЧто реально критичноЧто почти не важно
Веб-сёрфингRTT: каждое новое соединение начинается с рукопожатий, и они складываютсяjitter, полоса сверх десятков мегабит
Видеозвонкиjitter и потери, они бьют напрямую по звукуабсолютная скорость
Игрыjitter и потери пачками, стабильность важнее среднегополоса, там копейки трафика
Скачивание большого файлапотери (см. таблицу выше) и полосаjitter
Просмотр видеостабильность полосы, буфер плеера сглаживает остальноеRTT, jitter
Прокси и VPNпотери плюс эффект TCP внутри TCPсредний RTT сам по себе

Отдельно про последнюю строку. Когда TCP-соединение едет внутри другого TCP-соединения, оба слоя начинают независимо реагировать на одни и те же потери и мешают друг другу: внешний уже перепослал, а внутренний тоже решил перепослать. Получается затор от одной-единственной пробки. Разбирал это подробно в сравнении протоколов, тут просто отмечу, что на рваном канале эффект вылезает первым делом, и именно поэтому протоколы поверх UDP на плохих линиях чувствуют себя заметно лучше.


Частые ошибки

  • Смотреть на avg и радоваться. Средняя прячет ровно те выбросы, которые вы и ощущаете. Смотрите max и mdev.
  • Судить о канале по десяти пакетам. Проблема, которая всплывает раз в минуту, в пятисекундном замере не появится.
  • Паниковать от красного посередине mtr. Если на последнем хопе ноль - потерь нет, вам просто не отвечал промежуточный роутер.
  • Мерить по Wi-Fi. Вы диагностируете свою квартиру, а не хостера.
  • Считать, что ping и рабочий трафик едут одинаково. Разный приоритет, разное отношение оборудования, при ECMP - буквально разные провода.
  • Игнорировать нагрузку. Bufferbloat в простое не виден в принципе. Тест без нагрузки его не поймает никогда.
  • Присылать в поддержку одну трассу. Обратный путь другой, без встречного отчёта половина картины отсутствует.
  • Гнаться за минимальным пингом любой ценой. Стабильные 60 мс лучше, чем 25 с выбросами до 300. Для всего живого предсказуемость дороже.
  • Верить одному замеру. Вечерний час пик - отдельная реальность, и именно в ней вы обычно и пользуетесь интернетом.

Где это проверять

Всё, что выше, требует второй точки. Пинг сам с собой не померишь: чтобы понять, дело в канале или в сервисе, нужна машина на другом конце, про которую вы точно знаете, что с ней всё в порядке.

Дешёвый VPS в этой роли незаменим. На нём поднимается iperf3 -s, ставится irtt server, с него снимается встречный mtr - и внезапно все замеры становятся двусторонними и осмысленными. Плюс появляется возможность проверить главное перед покупкой чего-то серьёзного: как из вашей сети доезжает до этого конкретного дата-центра, потому что цифры в оффере про это не говорят ничего.

Я для такого держу самый младший тариф на serv.host (промокод promo22382) - под iperf3 и трассировки хватает минимальной конфигурации, а разные локации позволяют сравнить маршруты и выбрать тот, который до вас доезжает нормально.

Порядок первой диагностики нового сервера, если нужен готовый список:

  1. ping -c 300 -i 0.2 до сервера, смотрим max и mdev, не avg.
  2. mtr -rwzbc 200 в обе стороны, читаем последнюю строку.
  3. mtr -T -P 443 туда же, сравниваем с ICMP-версией.
  4. iperf3 -u -b 50M -t 30 - получаем честные jitter и потери.
  5. iperf3 -c ... -t 30 в один поток и -P 8 - разница покажет, есть ли фоновые потери.
  6. Пинг под нагрузкой в двух окнах - ловим bufferbloat.
  7. Повторить вечером. Обязательно.

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


Короткий итог

  • ping показывает одно усреднённое число туда-обратно. Ни направления, ни разброса, ни поведения под нагрузкой в нём нет.
  • ICMP - не ваш трафик. Роутеры ограничивают ответы на своём управляющем процессоре, провайдеры его душат, а при ECMP он вообще едет по другому физическому линку. Меряйте TCP-зондами на тот порт, которым пользуетесь.
  • Jitter превращается в потери на уровне приложения: пакет, опоздавший сильнее глубины буфера, выбрасывает сам приёмник, хотя сеть его честно доставила. Стабильные 80 мс лучше скачущих 20-200.
  • Один процент потерь при RTT 100 мс держит одно TCP-соединение на полутора мегабитах независимо от ширины канала. Отсюда «спидтест норм, а файл ползёт».
  • Bufferbloat - это когда большие буферы прячут от TCP сигнал перегрузки, и он разгоняется, пока задержка не улетает в сотни миллисекунд. В простое не виден вообще, ловится только замером под нагрузкой.
  • Лечится AQM: CoDel следит за временем в очереди, FQ-CoDel добавляет честное разделение потоков, CAKE делает всё сразу. На линуксе fq_codel обычно уже стоит по умолчанию.
  • В mtr реальны только те потери, что дошли до последней строки. Красное посередине - почти всегда ограничение ICMP на промежуточном роутере.
  • Половина проблем чинится на вашей стороне (роутер, Wi-Fi, qdisc, congestion control), вторая половина не чинится вообще и лечится только сменой маршрута, то есть переездом.

Хороший канал определяется не маленьким пингом, а тем, что этот пинг предсказуем и не разваливается, когда по каналу что-то поехало. Померить это ровно на пять минут дольше, чем набрать ping.


Вообще я микроразработчик, со мной можно связаться как угодно, я открыт ко всему

Сторонний мой проект: Zapret2UI.


Источники