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

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

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

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

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

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

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

Снимок экрана анализа проволочной акулы

Снимок экрана анализа проволочной акулы

Обновить:

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

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

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

9 ответов

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

sysctl -w net.ipv4.tcp_timestamps=0

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

Будьте очень осторожны при отключении опции TCP Window Scale. Эта опция важна для обеспечения максимальной производительности через Интернет. У кого-то с соединением 10 мегабит / сек будет субоптимальная передача, если время прохождения сигнала туда и обратно (в основном такое же, как пинг) больше 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?

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

"Решением было отключить масштабирование tcp windows и tcp timestamp на наших серверах, которые доступны для общественности".

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

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

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

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

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

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

прослушать 80 бэклог = число

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

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

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

Другие вопросы по тегам