Назад | Перейти на главную страницу

Почему сервер не отправляет пакет SYN / ACK в ответ на пакет SYN

В последнее время нам стало известно о проблеме с TCP-соединением, которая в основном ограничивается пользователями Mac и Linux, которые просматривают наши веб-сайты.

С точки зрения пользователя, это очень долгое время соединения с нашими веб-сайтами (> 11 секунд).

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

По сути, происходит то, что клиентская машина отправляет SYN-пакет для установления TCP-соединения, а веб-сервер получает его, но не отвечает SYN / ACK-пакетом. После того, как клиент отправил много пакетов SYN, сервер наконец отвечает пакетом SYN / ACK, и все в порядке для оставшейся части соединения.

И, конечно же, главное в проблеме: это периодически и не происходит постоянно (хотя это случается в 10-30% случаев).

Мы используем Fedora 12 Linux в качестве ОС и Nginx в качестве веб-сервера.

Скриншот анализа wirehark

Обновить:

Отключение масштабирования окна на клиенте предотвратило возникновение проблемы. Теперь мне просто нужно разрешение на стороне сервера (мы не можем заставить всех клиентов делать это) :)

Окончательное обновление:

Решением было отключить оба Масштабирование окна TCP и Отметки времени TCP на наших серверах, которые доступны для всех.

У нас была точно такая же проблема. Простое отключение временных меток TCP решило проблему.

sysctl -w net.ipv4.tcp_timestamps=0

Чтобы сделать это изменение постоянным, сделайте запись в /etc/sysctl.conf.

Будьте очень осторожны при отключении параметра «Масштаб окна TCP». это вариант важен для обеспечения максимальной производительности через Интернет. У кого-то со скоростью 10 мегабит / сек передача будет неоптимальной, если время туда и обратно (в основном, как ping) более 55 мс.

Мы действительно заметили эту проблему, когда за одним NAT было несколько устройств. Я подозреваю, что сервер мог быть сбит с толку, увидев отметки времени с устройств Android и компьютеров OSX одновременно, поскольку они помещают совершенно разные значения в поля отметок времени.

В моем случае следующая команда устранила проблему с отсутствующими ответами SYN / ACK с сервера Linux:

sysctl -w net.ipv4.tcp_tw_recycle=0

Я думаю, что это более правильно, чем отключать временные метки TCP, поскольку временные метки TCP полезны для высокая производительность (PAWS, масштабирование окна и т. Д.).

Документация по tcp_tw_recycle явно заявляет, что не рекомендуется включать его, поскольку многие маршрутизаторы NAT сохраняют метки времени и, таким образом, срабатывает PAWS, поскольку метки времени с одного и того же IP-адреса несовместимы.

   tcp_tw_recycle (Boolean; default: disabled; since Linux 2.4)
          Enable fast recycling of TIME_WAIT sockets.  Enabling this
          option is not recommended for devices communicating with the
          general Internet or using NAT (Network Address Translation).
          Since some NAT gateways pass through IP timestamp values, one
          IP can appear to have non-increasing timestamps.  See RFC 1323
          (PAWS), RFC 6191.

Просто интересно, а почему для пакета SYN (кадр № 539; тот, который был принят) в столбце «Информация» отсутствуют поля WS и TSV?

WS - это Масштабирование окна TCP а TSV - это Значение отметки времени. Оба они находятся в поле tcp.options, и Wireshark все равно должен отображать их, если они есть. Может быть, стек TCP / IP клиента повторно отправил другой SYN-пакет с 8-й попытки, и это было причиной, по которой он был внезапно подтвержден?

Не могли бы вы предоставить нам внутренние ценности фрейма 539? Всегда ли SYN / ACK приходит для пакета SYN, для которого не включен WS?

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

«Решением было отключить масштабирование окон TCP и временные метки tcp на наших серверах, которые доступны для всех».

Чтобы продолжить то, что заявил Ансис, я видел подобные проблемы, когда брандмауэр не поддерживает масштабирование TCP Windows. Межсетевой экран какой марки / модели находится между этими двумя хостами?

Отсутствие SYN / ACK может быть вызвано слишком низкими пределами защиты SYNFLOOD на брандмауэре. Это зависит от того, сколько подключений к вашему серверу создает пользователь. Использование spdy уменьшит количество подключений и может помочь в ситуации, когда поворот net.ipv4.tcp_timestamps офф не помогает.

Это поведение слушающего TCP-сокета, когда его очередь заполнена.

Ngnix позволяет аргументу backlog для прослушивания быть установленным в конфигурации: http://wiki.nginx.org/HttpCoreModule#listen

прослушать 80 невыполненных работ = число

Попробуйте установить для num значение больше значения по умолчанию, например 1024.

Я не гарантирую, что полная очередь на прослушивание действительно является вашей проблемой, но это хорошая вещь, которую стоит проверить в первую очередь.

Я только что обнаружил, что TCP-клиенты Linux изменяют свой пакет SYN после 3 попыток и удаляют параметр масштабирования окна. Думаю, разработчики ядра посчитали, что это частая причина сбоев соединения в Интернете.

Это объясняет, почему этим клиентам удается подключиться через 11 секунд (TCP SYN без окон происходит через 9 секунд в моем кратком тесте с настройками по умолчанию)

У меня была аналогичная проблема, но в моем случае это была контрольная сумма TCP, которая была вычислена неправильно. Клиент был за veth, и команда ethtool -K veth0 rx off tx off сделала свое дело.