RE:NODE

Сеть13 мин чтения

Задержка, джиттер и потеря пакетов: как отличить лаг

Игроки называют лагом всё подряд. У трёх явлений разные причины и разные способы лечения, а шестидесятисекундный тест ping показывает, с каким из них вы имеете дело.

Обновлено

0 прочтений

Всё, что неприятно ощущается в сети, называют лагом, и поэтому так много времени тратится на починку не того. Есть три разных измерения, у них разные причины, и одна минута ping показывает, какое из них у вас.

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

Три числа и как каждое ощущается#

ИзмерениеЧто этоЧто говорят игроки
Задержка (RTT)Время на путь туда и обратно, в миллисекундах«Всё происходит с опозданием»
ДжиттерРазброс этого времени«Дёргается, хотя пинг нормальный»
Потеря пакетовДоля пакетов, которые не дошли, в процентах«Люди телепортируются» или «мои выстрелы не засчитываются»

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

МаршрутПримерное расстояниеФизический минимумРеальный RTT
Берлин - Франкфурт450 km5 ms8-12 ms
Лондон - Франкфурт650 km7 ms12-18 ms
Стамбул - Франкфурт2,000 km20 ms30-45 ms
Тбилиси - Франкфурт3,000 km30 ms40-70 ms
Нью-Йорк - Франкфурт6,200 km62 ms85-110 ms

Джиттер - это то, что на самом деле портит игры. Игровой клиент - это движок предсказания: он угадывает, где всё будет, и поправляется, когда сервер говорит иначе. Постоянную задержку легко предсказать. Задержку, скачущую между 30 и 140 мс, - нет, и эти поправки игроки ощущают как рывки назад и неточные попадания. До 5 мс - отлично, до 15 мс - нормально, выше 30 мс - испорченная игра, что бы ни говорило среднее значение.

Потеря пакетов - это «да или нет» для каждого пакета и статистика в целом. Ниже 0,1% никто ничего не замечает. От 0,5% до 2% шутер ощущается неправильно, а игра на выживание в основном нет. Выше 2% неправильно ощущается всё. Распределение важнее самого числа: 2%, равномерно рассыпанные, переносимы, а 2% в виде пачки из сорока потерянных подряд пакетов раз в минуту - это отключение с дополнительными шагами.

Стабильные 90 мс играются лучше, чем скачущие 40. В игре предсказуемость важнее скорости.

Куда на самом деле уходят миллисекунды#

Число в углу экрана - это не вся задержка между нажатием клавиши и результатом на экране. Знание остального бюджета избавляет от погони за 10 мс сети, когда 80 мс сидят где-то ещё.

От ввода до кадра8-20 мсКлиент - серверполовина RTTТик серверадо одного тикаСервер - клиентполовина RTTИнтерполяциябуфер 20-100 мсНа экране10-30 мс
Куда уходит время кругового пути

Две из этих стадий стоит понять как следует.

Тик. Сервер обрабатывает мир дискретными шагами. Ваш ввод приходит в какой-то момент внутри шага и не обрабатывается до следующего, так что сервер с 20 тиками в секунду добавляет до 50 мс и в среднем 25. При 64 тиках в секунду это до 15,6 мс. Именно поэтому вообще упоминают частоту тиков, и поэтому её повышение стоит CPU, а не пропускной способности - весь компромисс описан в статье что на самом деле означает tick rate.

Буфер интерполяции. Клиенты намеренно рисуют мир чуть в прошлом, чтобы опоздавший пакет не давал видимого провала. В старых играх на движке Source это было явно и настраивалось: cl_interp_ratio 2 при cl_updaterate 66 буферизует два обновления, то есть около 30 мс намеренной задержки. Новые игры задают это сами и в основном не показывают настроек. Буфер - причина, по которой игра может ощущаться гладкой при 100 мс и ужасной при скачущих 40: буфер поглощает постоянную задержку, но не разброс.

Как отличить их за шестьдесят секунд#

Одна команда. Запустите её на сто пакетов, а не на пять.

bash
$ ping -c 100 -i 0.2 play.example.com--- play.example.com ping statistics ---100 packets transmitted, 100 received, 0% packet loss, time 19871msrtt min/avg/max/mdev = 41.2/43.8/58.1/2.4 ms

Итоговая строка отвечает на все три вопроса:

  • 0% packet loss и низкий mdev при высоком avg: чистая задержка. Сервер далеко или маршрут плохой. Ничто на сервере этого не исправит.
  • Низкий avg и max в несколько раз больше min, при mdev выше примерно 10: джиттер. Сначала посмотрите на собственное подключение клиента.
  • Любое значение выше 0% потерь, если оно устойчиво: потеря пакетов. Найдите узел.
  • Все три в норме, а игра всё равно ощущается плохо: это не сеть. Переходите к разделу про сервер.

mdev - это среднее отклонение, и как показатель джиттера оно достаточно хорошо. Windows его не выводит, поэтому смотрите на разброс между Minimum и Maximum:

Windows
ping -n 100 play.example.com

Две оговорки о ping, которые важны. Он использует ICMP, а игра - TCP или UDP на конкретном порту, поэтому файрвол или ограничитель скорости могут обращаться с ними по-разному: mtr --tcp --port 25565 или --udp проверяет настоящее. И пинг адреса сервера проверяет путь, а не игру: сервер, загруженный на 100% CPU, отвечает на пинги мгновенно, а его мир работает вполовину медленнее.

Как читать отчёт mtr и не дать себя обмануть#

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

bash
$ mtr -rwzbc 200 play.example.comHOST                                 Loss%  Snt  Last   Avg  Best  Wrst StDev 1. AS???    192.168.1.1               0.0%  200   0.6   0.7   0.5   2.1   0.2 2. AS12345  10.0.0.1                  0.0%  200   8.1   8.6   7.9  18.4   1.1 3. AS12345  core1.isp.example        14.0%  200  11.2  11.9  10.8  29.1   2.0 4. AS3356   ae-1.fra.example.net       0.0%  200  38.4  38.9  38.1  44.2   0.8 5. AS64500  play.example.com           0.0%  200  41.0  41.6  40.9  48.7   1.2

Этот отчёт показывает здоровый путь. 14% на узле 3 - не потеря, и классическая ошибка - читать это как потерю.

  • Потеря на промежуточном узле, которая не продолжается до конца, не настоящая. Маршрутизаторы понижают приоритет ICMP, адресованного им самим, а трафик пересылают отлично. Только потеря, которая появляется на узле и сохраняется на каждом следующем, - это потеря, от которой страдает ваш трафик.
  • Считается последняя строка. Если на последнем узле 0% потерь, то на вашем пути потерь нет, как бы ни выглядела середина отчёта.
  • Скачок задержки на одном узле - это нормально: так выглядит дальний канал. Скачок, который продолжает расти на каждом следующем узле, - это перегрузка.
  • Обратный путь невидим. mtr показывает только прямой маршрут, а маршруты в интернете часто несимметричны. Если отчёт чист, а проблема настоящая, запустите mtr и от сервера к игроку. Плохой узел нередко прячется именно там.
  • Запускайте во время проблемы. Чистый отчёт в три часа дня ничего не доказывает про вечер, который разваливается в 20:00, а это в точности признак перегруженного стыка между сетями.

Подробнее о разборе отчёта рассказано в статье как читать traceroute и mtr, а WinMTR делает ту же работу в Windows.

Джиттер: bufferbloat, wifi и очередь в вашем собственном доме#

Большая часть джиттера возникает в двадцати метрах от игрока.

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

Проверьте за тридцать секунд: запустите непрерывный пинг, затем начните большую отправку и следите за цифрами. Если они выросли втрое, это bufferbloat. Лечится интеллектуальным управлением очередью - fq_codel или cake - на маршрутизаторе, с ограничителем скорости примерно на 85-90% от измеренной скорости линии, чтобы очередь образовывалась в оборудовании, которым вы управляете, а не у провайдера. В OpenWrt это называется SQM, а несколько бытовых маршрутизаторов называют это Smart Queue.

Wifi - вторая половина. Повторно отправленный кадр приходит поздно, а не никогда, поэтому wifi даёт джиттер, а не потерю. Диапазон 2.4 GHz делит спектр со всеми соседями и большинством микроволновок, 5 GHz может без предупреждения сменить канал, обнаружив радар, а mesh-системы, где одно радио обслуживает и клиентов, и магистральный канал, вдвое сокращают эфирное время. Кабель убирает всё это и остаётся самым ценным, что может сделать жалующийся игрок. Powerline-адаптеры по непредсказуемости равны wifi, и относиться к ним нужно так же.

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

Потеря пакетов: что она делает с TCP и с UDP#

Симптом целиком зависит от протокола, поэтому одни и те же 2% потерь порождают две совершенно разные жалобы.

Игры на TCP замирают и догоняют. TCP гарантирует доставку и порядок, поэтому потерянный пакет останавливает всё, что идёт за ним, пока не придёт повторная отправка, а это стоит как минимум одного кругового пути. Minecraft Java работает на TCP, поэтому потеря там проявляется как полусекундная пауза, за которой всё происходит разом, а не как телепортация.

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

Откуда на самом деле берётся потеря, примерно в порядке частоты:

  1. Насыщенный исходящий канал, обычно у самого игрока. Полная очередь отправки сбрасывает пакеты, когда буфер заполнен, - это финал описанного выше bufferbloat.
  2. Wifi или плохой кабель. Повреждённый кабель или несовпадение дуплекса дают небольшую постоянную потерю, которую ничем другим не объяснить.
  3. Перегруженный канал где-то посередине, появляющийся в одни и те же часы каждый день.
  4. Переполнение сокетных буферов самого сервера, когда процесс не успевает читать. В Linux netstat -su показывает ошибки приёмного буфера, и это пакеты, которые машина получила и выбросила.
  5. MTU blackhole, который вообще не потеря, но для больших пакетов выглядит так же. Проверьте напрямую: ping -M do -s 1472 play.example.com в Linux или ping -f -l 1472 play.example.com в Windows отправляет пакет в 1500 байт, который нельзя фрагментировать. Если малые пинги проходят, а этот нет, путь не пропускает пакеты полного размера, и причина обычно в каком-то туннеле.

Когда виноват сервер, а не сеть#

Эту категорию диагностируют неверно с самыми дорогими последствиями, потому что люди покупают тариф побольше, чтобы починить маршрутизатор в собственной гостиной, или переносят сервер, чтобы починить плагин.

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

Частые причины:

  • CPU на пределе. Один контейнер, жёсткое ограничение на купленную долю и игровой цикл, который не укладывается вовремя. Сервер на 100% - медленный, а не сломанный. О том, как честно прочитать это, рассказано в статьях CPU или RAM для игровых серверов и как читать график нагрузки сервера.
  • Один дорогой тик. Автосохранение, пишущее большой мир, всплеск генерации чанков, плагин, обращающийся к базе данных в основном потоке. В Minecraft это проявляется всплесками MSPT, а не постоянной нагрузкой, и spark их находит - диагностика лагов с помощью spark.
  • Нехватка памяти. Пауза сборщика мусора останавливает мир на столько, сколько ей нужно, а сервер на пределе памяти хуже сервера с запасом. Случай Minecraft разобран в статье почему падает TPS.
  • Шумный сосед на общем оборудовании, который выглядит как эпизодическая медлительность без локального объяснения - общий CPU и шумные соседи.

В RE:NODE консоль панели показывает графики памяти, CPU и диска относительно лимитов тарифа, и это самый быстрый способ отличить «моему серверу не хватает CPU» от «моя сеть теряет пакеты» до того, как тратить деньги на то или другое. То, что стоит настроить до того, как начнутся жалобы, описано в статье мониторинг, который что-то говорит.

Что можно исправить, по порядку#

Сначала самое дешёвое и эффективное. Большинство групп останавливаются после третьего шага.

  1. Измерьте, прежде чем что-то менять. Сто пакетов пинга и один mtr от каждого жалующегося игрока. Запишите цифры. Половина всех сообщений о лагах - это один человек на wifi.
  2. Подключите кабелем самого громкого жалобщика. Это ничего не стоит и само по себе снимает удивительно много жалоб на джиттер.
  3. Исправьте bufferbloat на маршрутизаторе. Тоже бесплатно, тоже недооценено, и это устраняет вечерние жалобы, совпадающие с тем, что дома есть кто-то ещё.
  4. Докажите, где потеря, с обеих сторон. Потеря на обратном пути со стороны игрока невидима. Если она внутри сети одного провайдера, единственное настоящее решение - обращение к этому провайдеру с приложенным отчётом mtr.
  5. Разместите сервер там, где большинство ваших игроков. Задержка - это расстояние, и ничто этого не изменит. RE:NODE работает в одной локации, в Германии, что разумная середина для игроков из Грузии, Турции, Восточной и Западной Европы и плохой выбор для группы в Австралии. Честный разбор этого решения - в статье где должен жить ваш сервер.
  6. Исправьте бюджет тика сервера, если цифры говорят, что проблема в сервере: дальность прорисовки, число сущностей, плагин, который что-то делает на каждом тике.
  7. Примите нижнюю границу. Когда пинг стабилен и соответствует расстоянию, это то, что даёт маршрут, и никакой тариф, частота тиков или протокол этого не изменят.

FAQ#

Какой пинг хорош для игрового сервера?

Ниже 30 мс почти не отличается от локального для практически всего. От 30 до 60 мс - нормально для выживания, строительства и ролевых игр, а в шутере заметно, если приглядеться. От 60 до 100 мс - играбельно, и именно здесь начинают жаловаться соревновательные игроки. Выше 120 мс это уже другой опыт, а не худшая версия того же.

Какая потеря пакетов допустима?

Ниже 0,1% никто не замечает. Около 1% шутер ощущается ненадёжным. Выше 2% - сломан. Пачки потерь намного хуже той же доли, распределённой равномерно, так что судите по картине, а не по итоговому числу.

Почему пинг нормальный, а игра всё равно подтормаживает?

Потому что задержка не в сети. Либо сервер пропускает тики, и это проблема CPU или плагина, либо клиент роняет кадры, и это локальная проблема. Ровный пинг при тормозящей игре - самый ясный сигнал, что сеть не виновата.

Уменьшит ли пинг переход на более крупный тариф?

Нет. Задержку задаёт расстояние, а тариф побольше не передвигает машину. Больше CPU помогает, когда сервер не успевает завершать тики, но это другой симптом, к которому просто приложена похожая жалоба.

Что хуже - джиттер или высокая задержка?

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

Может ли VPN уменьшить лаг?

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


Комментарии

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

0/2000