Медленный линк без видимой причины и первые шаги диагностики

Жалоба звучит знакомо каждому администратору: сервер вроде жив, диски не скрипят, процессор не раскалён, а файл размером в гигабайт копируется по сети десять минут. Пользователи ругаются, мониторинг молчит, и первое желание - обвинить приложение. Честно говоря, в доброй половине таких случаев виноват не софт, а самый нижний уровень: сетевой интерфейс, который тихо договорился со свитчом на 100 Mb/s Half duplex вместо положенных 1000 Mb/s Full. Это классический footgun auto-negotiation: всё "работает", линк есть, пинги бегают, но реальная полоса просела в десять раз, а duplex mismatch добавляет потери пакетов. Хорошая новость в том, что диагностируется это за минуту с помощью ethtool, и дальше статья разбирает весь путь от первого взгляда на линк до устойчивого исправления.

Базовый диагноз с ethtool и чтение Speed Duplex Link detected

Первое действие на подозрительном сервере предельно простое:

ethtool eth0

Типовой вывод на больной машине выглядит так:

Settings for eth0:
        Supported ports: [ TP ]
        Supported link modes:   10baseT/Half 10baseT/Full
                                100baseT/Half 100baseT/Full
                                1000baseT/Full
        Supported pause frame use: Symmetric
        Supports auto-negotiation: Yes
        Advertised link modes:  10baseT/Half 10baseT/Full
                                100baseT/Half 100baseT/Full
        Advertised pause frame use: Symmetric
        Advertised auto-negotiation: Yes
        Speed: 100Mb/s
        Duplex: Half
        Port: Twisted Pair
        PHYAD: 1
        Transceiver: internal
        Auto-negotiation: on
        MDI-X: on (auto)
        Link detected: yes

Разбор по ключевым строкам. Supported link modes перечисляет всё, что умеет карта: здесь и 10, и 100, и 1000 Мбит, значит железо исправно и гигабит ему доступен. Advertised link modes - это то, что карта сама предлагает партнёру по кабелю во время auto-negotiation, и вот тут уже видно подвох: гигабитный режим 1000baseT/Full в список не попал. Speed показывает фактическую скорость установленного линка - 100Mb/s, а Duplex: Half означает, что больше одной стороны одновременно передавать не может, коллизии и ретрансляции обеспечены. Link detected: yes говорит, что физический линк поднят, то есть кабель вставлен и сигнал есть, но качество соглашения оставляет желать лучшего. Поле MDI-X время от времени вводит в заблуждение: оно про автоопределение прямого или кроссового кабеля, к скорости отношения не имеет.

Здоровый вывод для сравнения содержал бы Speed: 1000Mb/s, Duplex: Full и 1000baseT/Full среди advertised режимов. Разница в пропускной способности не двадцать процентов, а порядок: гигабит Full duplex даёт на практике около 940 Мбит/с полезного TCP-трафика, а 100 Half едва вытягивает 40-45 Мбит/с с потерями.

Драйвер прошивка и счётчики ошибок как вторая линия улик

Следующий шаг - понять, какой драйвер обслуживает интерфейс и насколько свежая у него прошивка:

ethtool -i eth0
driver: e1000e
version: 3.8.4-NAPI
firmware-version: 0.5-3
expansion-rom-version:
bus-info: 0000:00:19.0
supports-statistics: yes
supports-test: yes
supports-eeprom-access: yes
supports-register-dump: yes
supports-priv-flags: yes

Здесь важны три поля: driver показывает модуль ядра (для серверных Intel-адаптеров чаще всего e1000e, igb или ixgbe, у Realtek встречается r8169, известный капризным поведением на гигабите), firmware-version позволяет сверить прошивку PHY с рекомендованной вендором, а bus-info пригодится, чтобы сопоставить интерфейс со слотом PCI и не перепутать порты на четырёхголовой карте. Старые версии r8169, например, исторически имели ошибки в реализации auto-negotiation, и обновление на r8168 от производителя решало проблему без замены железа.

Теперь статистика ошибок:

ethtool -S eth0 | grep -iE "error|crc|drop|collision"
     rx_crc_errors: 14832
     rx_errors: 14901
     tx_errors: 0
     rx_missed_errors: 17
     collisions: 9204
     rx_length_errors: 0
     rx_over_errors: 0
     rx_frame_errors: 264
     tx_aborted_errors: 0

Это уже похоже на признание вины. Поле rx_crc_errors росло на десятки в секунду - значит, кадры доезжают битыми, что типично для повреждённого кабеля, плохого коннектора или duplex mismatch. Счётчик collisions приличен сам по себе для Half duplex, но если Duplex: Full, а коллизии копятся, это верный признак, что вторая сторона линка работает в Half - классический mismatch, когда одна сторона смотрит на передачу партнёра как на коллизию, а вторая молча теряет кадры. Поле rx_missed_errors показывает, что карта не успевала забирать кадры, но здесь значения мизерные и вины системы нет. Общий приём: снимают значения ethtool -S дважды с интервалом в минуту и смотрят приросты - статические числа могут быть наследием прошлых лет, важна динамика.

Принудительная установка скорости и почему autoneg off опасен

Когда диагноз ясен, рука тянется исправить всё силой:

ethtool -s eth0 speed 1000 duplex full autoneg on

Команда устанавливает скорость 1000 Мбит/с, полный дуплекс и оставляет auto-negotiation включённым - для витой пары на гигабите это единственно корректный режим, потому что стандарт 1000base-T прямо требует автосогласования для выбора master/slave и синхронизации тактирования. Вариант с autoneg off выглядит заманчиво, но таятся два подводных камня. Первый: при выключенной автосогласованности карта перестаёт сообщать партнёру свои возможности, и свитч по стандарту обязан откатиться на 100base-TX Half duplex - получаем ровно тот footgun, с которого начали. Второй: принудительная установка действует до перезагрузки или до переподнятия интерфейса, и после ребута всё вернётся на круги своя, если настройку не зафиксировать в конфигурации NetworkManager (параметры 802-3-ethernet.speed и 802-3-ethernet.duplex в nmcli) или в /etc/network/interfaces через pre-up ethtool.

Ключевая разница подходов: auto-negotiation - это переговоры, где обе стороны публикуют список режимов и выбирают лучший общий, а принудительная фиксация - односторонний приказ, который партнёр может не понять. На оптических линках 1G SFP фиксация скорости иногда оправдана и даже требуется вендором, но на меди правило простое: либо обе стороны в autoneg, либо жди неприятностей. Проверка после любых изменений - снова ethtool eth0 и контроль строк Speed и Duplex, плюс повторный iperf3.

Кабель и порт свитча как физические виновники просадки

Сценарий из жизни: сервер пять лет стоял в стойке, тянул гигабит, и вдруг после перестановки скорость упала до 100 Мбит. Виноват оказался патч-корд. Кабель категории 5 официально рассчитан на 100base-TX, и хотя короткий целый кусок cat5 иногда поднимает гигабит, стоит появиться одной плохой обжимке или повреждённой паре - и auto-negotiation честно договаривается до сотни. Гигабитный 1000base-T использует все четыре пары витой пары, тогда как 100base-TX довольствуется двумя. Перебитая или непропаянная пара в кабеле cat5 означает: сотня есть, гигабита не будет никогда. Категории 5e и 6 гарантируют нужные характеристики затухания и перекрёстных наводок, поэтому для серверной патч-корды категории не ниже 5e - не роскошь, а гигиена.

Проверка со стороны свитча не менее обязательна. На управляемом свитче смотрят состояние порта: счётчики CRC на стороне свитча, history логов link up/down, настроенный режим порта. Нередко порт на свитче кто-то когда-то зафиксировал в 100 full "для надёжности", и тогда сервер с autoneg получает ровно то, что ему диктуют, либо duplex mismatch, если времена фиксации на двух сторонах разошлись. Быстрый тест без доступа к свитчу - переставить патч-корд в соседний заведомо гигабитный порт и посмотреть, изменится ли Speed в выводе ethtool. Если скорость поднялась - виноват порт или его конфигурация, если нет - кабель или сама карта. На заметку: iperf3 между сервером и заведомо здоровым соседом подтверждает диагноз цифрой, а не ощущением.

Замер реальной полосы с iperf3 и обход без ethtool

iperf3 - стандартный способ измерить пропускную способность, а не верить выводу ethtool на слово. На соседней машине запускают сервер:

iperf3 -s

На диагностируемом сервере - клиент:

iperf3 -c 192.168.10.5 -t 30 -P 4

Опция -t 30 задаёт длительность теста в 30 секунд, -P 4 поднимает четыре параллельных потока, что снимает ограничение одного TCP-окна. Здоровый гигабитный линк покажет суммарно 930-950 Mbits/sec. Линк 100 Mb/s Half duplex выдаст 30-45 Mbits/sec с приличным числом ретрансляций в колонке Retr - их счёт в выводе iperf3 хорошо коррелирует с collisions из ethtool -S.

Запасные пути, когда ethtool под рукой нет или он не поддержан драйвером. Ядро публикует скорость через sysfs - читается прямо из файла:

cat /sys/class/net/eth0/speed
cat /sys/class/net/eth0/duplex

Первый файл вернёт 100 или 1000, второй - full или half. Учтите: при опущенном линке чтение /sys/class/net/eth0/speed вернёт ошибку "Invalid argument", это нормально и означает лишь отсутствие линка. Утилита mii-tool из пакета net-tools - старейшая альтернатива, выводит что-то вроде "eth0: negotiated 100baseTx-HD, link ok", но считается устаревшей: она общается с PHY через устаревший MII-регистровый интерфейс, не знает про гигабитные и более скоростные режимы и на современных адаптерах часто врёт или не работает вовсе. Держите её в голове только как экспонат.

Лог link-событий смотрят в журнале ядра:

dmesg | grep -i eth0
journalctl -k | grep -i link
[   12.418203] e1000e 0000:00:19.0 eth0: NIC Link is Up 100 Mbps Half Duplex, Flow Control: None
[ 4210.771950] e1000e 0000:00:19.0 eth0: NIC Link is Down
[ 4213.884120] e1000e 0000:00:19.0 eth0: NIC Link is Up 100 Mbps Half Duplex, Flow Control: None

Периодические пары Link Down / Link Up в dmesg - отпечаток нестабильного контакта или проблем с портом свитча, а строка "Link is Up 100 Mbps Half Duplex" прямо фиксирует момент, когда карта согласовала убогий режим. Если интерфейс переименован через predictable names (enp0s25 и подобные), подставьте актуальное имя во все команды.

Пошаговый план администратора и профилактика повторений

Практический порядок действий на продакшене выглядит так:

  1. Выполнить ethtool eth0 и зафиксировать Speed, Duplex, Link detected, advertised режимы;
  2. Посмотреть ethtool -S eth0, повторить через минуту и оценить прирост crc_errors, rx_errors, collisions;
  3. Проверить dmesg и journalctl -k на предмет Link Down/Up и зафиксированной скорости;
  4. Прогнать iperf3 с соседним хостом для объективной цифры полосы и числа ретрансляций;
  5. Переставить кабель в заведомо исправный порт свитча и заменить патч-корд на cat5e или cat6;
  6. Проверить конфигурацию порта свитча, убрать ручную фиксацию скорости, оставить autoneg с обеих сторон;
  7. При необходимости принудительно выставить ethtool -s eth0 speed 1000 duplex full autoneg on и зафиксировать настройку в конфигурации сетевого менеджера, чтобы пережить перезагрузку.

Профилактика проста и дешевле ночных инцидентов. Мониторинг должен читать /sys/class/net/*/speed и опережающе алертить, если серверный интерфейс вдруг договорился ниже ожидаемой скорости - это одна строка в скрипте проверки и одна метрика для системы наблюдения. При приёмке нового сервера в стойку полезно сразу снять вывод ethtool и iperf3 как эталон, а при каждой смене патч-кордов фиксировать категорию кабеля. Маркируйте кабели, не жалейте cat6 на серверные порты и не позволяйте никому фиксировать скорость на портах свитча без ведома администраторов серверов. И храните эталонные выводы ethtool для каждого узла: когда через полгода что-то просядет, сравнение с эталоном сократит диагностику с часа до пяти минут.

Отдельного упоминания заслуживает привычка фиксировать диагностику в тикетах. Строка "Speed: 100Mb/s, Duplex: Half, crc_errors растут" в журнале инцидента экономит часы того, кто разберёт похожую жалобу через год. Администраторы с опытом знают: проблемы физического уровня почти никогда не лечатся сами, они лишь маскируются, пока нагрузка невелика, и всплывают в самый неудобный момент, например во время ночного бэкапа или бухгалтерской отчётности.

Медленная сеть почти всегда честно рассказывает о себе сама - нужно только знать, у кого спросить. ethtool спрашивает у карты и у PHY напрямую, dmesg помнит историю, iperf3 даёт беспристрастную цифру. Пять команд, десять минут, и загадочная "тормозящая сеть" превращается в конкретный патч-корд cat5, пережатый кабель-менеджером стойки.