MAATRIX / Блог / Маршрут короче на три хопа, а работает хуже: почему количество узлов ничего не значит

Маршрут короче на три хопа, а работает хуже: почему количество узлов ничего не значит

MAATRIX

Два маршрута до одного и того же сервера: в первом 9 хопов, во втором — 12. Логичный вывод «первый короче — значит быстрее» на практике регулярно оказывается неверным: девятихоповый маршрут может показывать RTT втрое хуже, чем двенадцатихоповый, и вдобавок скакать по задержке от пакета к пакету. Число строк в выводе traceroute — это количество узлов, ответивших на запрос, а не мера расстояния, скорости или качества. Разбираем, почему так, и на что смотреть вместо счёта хопов.

Что на самом деле считает traceroute, когда считает хопы

traceroute и mtr строят список хопов одним и тем же трюком: отправляют пакеты с постепенно растущим TTL (time to live) и ловят ICMP-ответ «время истекло» от каждого маршрутизатора на пути, который этот TTL обнулил. Первый пакет с TTL=1 гаснет на первом же роутере и получает от него ответ, второй с TTL=2 доходит на хоп дальше и гаснет там, и так далее — пока пакет не дойдёт до цели.

Отсюда первое, что стоит зафиксировать: хоп в выводе — это узел третьего уровня (L3, с собственным IP и готовностью отвечать ICMP), который случайно оказался на пути пакета. Это не единица расстояния и не единица времени. Хоп между двумя портами одного и того же коммутатора в одной стойке дата-центра и хоп между двумя магистральными маршрутизаторами на разных континентах в выводе traceroute выглядят абсолютно одинаково — одна строка, один IP, одна цифра задержки. Но по факту это два совершенно разных объекта: первый добавляет к общему времени пренебрежимо мало, второй может добавить значимую долю всего RTT, если на нём есть очередь, перегрузка или просто много физического расстояния до следующего узла.

Второе: не каждый узел на маршруте вообще попадает в вывод. Часть маршрутизаторов настроена не отвечать на ICMP time-exceeded (это осознанная политика безопасности некоторых операторов) — тогда в traceroute вы увидите звёздочки * * * вместо строки, и оценить, что происходит внутри этого участка, вообще не получится. Значит, само число видимых хопов — это ещё и функция настроек чужих сетей, а не только физической топологии.

Почему маршрут с большим числом хопов может оказаться быстрее

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

Маршрут А, короткий по числу хопов:

1  домашний роутер           0.4 ms
2  граница провайдера        2 ms
3  транзитный аплинк, узел 1 8 ms
4  транзитный аплинк, узел 2 65 ms   <- резкий скачок здесь
5  граница сети назначения   68 ms
6  сервер                    69 ms

Маршрут Б, тот же сервер, другой аплинк, длиннее по числу хопов:

1  домашний роутер           0.4 ms
2  граница провайдера        2 ms
3  локальный аплинк          3 ms
4  точка обмена трафиком     4 ms
5  магистральный узел 1      12 ms
6  магистральный узел 2      15 ms
7  магистральный узел 3      18 ms
8  граница сети назначения   19 ms
9  сервер                    20 ms

Маршрут А короче на три строки, но приходит к цели в три с лишним раза медленнее маршрута Б — потому что где-то между третьим и четвёртым хопом сидит один перегруженный или физически длинный участок (например, транзитный оператор, чей путь до этой точки идёт кружным путём или упирается в узкое место в час пик), и этот единственный проблемный линк сводит на нет всю «экономию» на количестве узлов. Маршрут Б, наоборот, идёт через качественный высокоуровневый транзит и точки обмена трафиком, где каждый отдельный переход между сетями почти ничего не стоит по задержке — итоговая сумма получается меньше, хотя строк в выводе больше.

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

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

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

MPLS и туннели: почему вывод traceroute не всегда показывает реальную топологию

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

Крупные магистральные и транзитные операторы часто строят свою внутреннюю сеть на MPLS (Multiprotocol Label Switching) или похожих технологиях туннелирования и инкапсуляции. Внутри такого MPLS-домена пакет физически проходит через цепочку маршрутизаторов, но с точки зрения обработки TTL эти узлы могут вести себя иначе, чем обычные IP-роутеры на границе сети:

  • Часть операторов настраивает так называемый TTL-tunneling (не декрементировать TTL пользовательского пакета на промежуточных MPLS-узлах, а декрементировать только TTL самой метки) — тогда весь внутренний путь внутри MPLS-облака физически проходит через несколько маршрутизаторов, но в traceroute это выглядит как один скачок между узлом на входе в облако и узлом на выходе из него, с одним резким приростом задержки на этом «хопе», хотя внутри него могло быть несколько реальных устройств.
  • Другая, более прозрачная настройка (ICMP tunneling / TTL propagation через MPLS-метки) наоборот показывает внутренние узлы MPLS-домена, но иногда с характерными пометками вроде MPLS Label=... рядом со строкой хопа — это уже видимый, но нетипичный формат вывода, который не все версии traceroute/mtr показывают одинаково.
  • Балансировка нагрузки внутри сети оператора (ECMP, equal-cost multi-path) может приводить к тому, что последовательные пакеты одной трассировки физически идут разными путями через разные параллельные маршрутизаторы одного уровня, но в выводе traceroute это выглядит как один «шумный» хоп с разными IP на одном и том же TTL, а не как явное ветвление маршрута.

Практический вывод из этого прост: число строк в выводе traceroute — это не число физических маршрутизаторов на пути пакета, а число узлов, которые решили себя показать именно так, как их видит эта конкретная утилита с этими конкретными настройками TTL. Оператор может физически прогонять трафик через дюжину устройств внутри своего MPLS-облака и показать это одним хопом с одной цифрой задержки — а другой оператор с точно такой же физической топологией покажет все internal-узлы построчно. Сравнивать «9 хопов у одного против 15 у другого» в такой ситуации — сравнивать не топологию сетей, а настройки видимости TTL у операторов, которые к качеству маршрута отношения не имеют.

Что на самом деле определяет качество маршрута

Раз число хопов ничего не гарантирует и не всегда отражает реальность, встаёт вопрос — на какие метрики смотреть вместо него. Их три, и вместе они дают куда более честную картину, чем подсчёт строк:

  • Итоговый RTT (round-trip time) до цели. Не задержка на промежуточном хопе, а именно финальная цифра — время до самого сервера, а не до какого-то узла посередине. Это сумма всех участков маршрута, честная и не зависящая от того, сколько строк было в выводе по пути.
  • Джиттер — стабильность этой задержки от пакета к пакету. Маршрут с невысоким средним RTT, но большим разбросом, на практике часто хуже маршрута с чуть более высоким, но стабильным RTT — особенно для голосовой связи, видео и игр, где важна не средняя цифра, а предсказуемость каждого конкретного пакета. Подробно о том, почему джиттер регулярно важнее среднего пинга и как его измерить, разобрано в статье джиттер важнее среднего пинга.
  • Потери пакетов (packet loss), особенно устойчивые, а не разовые. Небольшие потери на одном промежуточном хопе, которые не повторяются на следующих и не доходят до цели, обычно не проблема — часть маршрутизаторов сама ограничивает частоту ответов на ICMP и рационально «теряет» часть диагностических пакетов, оставаясь полностью исправной для реального трафика. А вот стабильные потери, которые прослеживаются до самого сервера, — это уже сигнал реальной проблемы независимо от того, на каком по счёту хопе они начались.

Ни одна из этих трёх метрик не зависит от того, сколько строк было в выводе traceroute перед финальным ответом. Маршрут с 6 хопами и маршрут с 16 хопами могут дать идентичный RTT, джиттер и потери — если на длинном маршруте каждый переход между сетями быстрый и качественный, а на коротком один из немногих переходов — узкое место.

Как правильно тестировать маршрут, а не считать строки в выводе

Практическая методика проще, чем кажется, и не требует ничего, кроме стандартных сетевых утилит на любом Linux-сервере.

  1. Гоняйте mtr, а не разовый traceroute. traceroute даёт один снимок в момент запуска — этого недостаточно, чтобы отличить устойчивую проблему от разовой флуктуации. mtr в отчётном режиме с достаточным числом циклов накапливает статистику по каждому хопу и по цели в целом:
mtr -rwzbc 200 target-server-ip

Флаги: -r — вывод в виде отчёта, а не интерактивного экрана, -w — полные имена хостов без сокращений, -z — номера AS на каждом хопе, если провайдер их отдаёт, -b — показывать одновременно имя и IP, -c 200 — 200 циклов опроса для статистически осмысленной картины.

  1. Смотрите на колонки Avg, Best/Wrst и StDev в строке самого сервера (последней), а не на количество строк над ней. Avg — средний RTT до цели, StDev — фактическая мера того самого джиттера, разрыв между Best и Wrst — амплитуда разброса. Именно эти три числа в последней строке отвечают на вопрос «маршрут хороший или плохой», а не число строк в отчёте.
  1. Найдите хоп, где резко растёт задержка, и оцените, насколько сильно он влияет на итог. Если скачок происходит на середине маршрута, а дальше задержка почти не растёт — узкое место именно там, и полезно понять, чей это участок (по имени хоста или ASN), чтобы при необходимости обсудить это с провайдером или сменить локацию/аплинк.
  1. Сравнивайте маршруты по колонке итогового RTT и Loss%, а не по числу хопов над ними. Если нужно сравнить двух провайдеров или два дата-центра, прогоните mtr до одной и той же цели с обеих точек и сравните именно финальные цифры, а не длину списка сверху.
  1. Повторяйте тест в разное время суток. Маршрут, идеальный ночью, может деградировать в вечерний пик, когда транзитный канал загружен другим трафиком клиентов того же оператора — а число хопов при этом не изменится ни на единицу, изменится только реальная задержка на перегруженных участках.

Когда число хопов всё-таки стоит смотреть — но не как приговор

Это не значит, что колонка с номером хопа бесполезна целиком — как диагностический ориентир, а не как самостоятельная метрика, она вполне пригодится:

  • Резкое изменение числа хопов до одной и той же цели со временем — сигнал, что маршрут поменялся (сеть перезаключила пиринг, изменила BGP-политику, произошла авария на прежнем пути). Это повод перепроверить RTT и джиттер заново, а не сам по себе показатель ухудшения или улучшения.
  • Хоп, на котором маршрут «упирается» в звёздочки и не идёт дальше, при этом до цели ответы всё же приходят — обычно значит, что конкретный узел просто не отвечает на ICMP, и это не авария, а настройка. Но если ответов не приходит вообще и до самой цели — это уже настоящий обрыв или блокировка, а не оформление вывода.
  • Сравнение двух маршрутов от одной точки до одной цели через разных провайдеров — тут число хопов в паре с итоговым RTT действительно может дать косвенный намёк, у кого маршрутизация выстроена аккуратнее: скачок задержки на большинстве промежуточных хопов против ровного нарастания на всём пути — разные профили сети, и это стоит учитывать наравне с итоговой цифрой.

В любом из этих сценариев число хопов работает как одна из деталей общей картины, а не как самостоятельный вердикт «этот маршрут лучше, потому что короче». Финальное решение всегда должно опираться на RTT, джиттер и потери, а не на подсчёт строк.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Если у меня в mtr 20 хопов до сервера — это плохо само по себе?

Нет, само по себе число ничего не говорит. Важно, что показывает последняя строка — итоговый RTT, StDev и Loss% до самого сервера. 20 хопов с ровной, низкой и стабильной задержкой — совершенно нормальный, качественный маршрут.

Почему у одного и того же сервера traceroute и mtr иногда показывают разное число хопов?

Утилиты могут по-разному обрабатывать TTL, использовать разные протоколы зондирования (ICMP, UDP, TCP) и получать разный ответ от узлов, которые реагируют избирательно на конкретный тип пакета. Плюс балансировка нагрузки (ECMP) у оператора может отправлять последовательные зонды по чуть разным путям. Расхождение в одну-две строки между запусками или утилитами — это нормально, а не признак ошибки измерения.

Можно ли по числу хопов прикинуть физическое расстояние до сервера?

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

Если маршрут короче по хопам, но RTT выше — стоит ли жаловаться провайдеру?

Стоит, но аргументом должен быть именно RTT, джиттер и потери с привязкой к конкретному хопу, где виден скачок задержки (по IP или ASN), а не формулировка «у вас слишком длинный маршрут». Провайдер физически не может и не должен гнаться за минимальным числом хопов — его задача обеспечить приемлемую итоговую задержку и стабильность, а как именно устроена внутренняя топология, второй вопрос.

MPLS — это что-то, что нужно специально включать или отключать на своей стороне?

Нет, это технология на стороне операторов магистральных сетей, а не что-то, что настраивается на вашем сервере или у конечного пользователя. С вашей стороны важно только понимать, что если вывод traceroute выглядит «подозрительно коротким» для межконтинентального маршрута — это, скорее всего, следствие MPLS-туннелирования у оператора на пути, а не ошибка измерения.

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

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →