Вопрос Приложение, застрявшее в повторной передаче TCP


Я запускаю ядро ​​Linux 3.13 (Ubuntu 14.04) на двух виртуальных машинах, каждый из которых работает на двух разных серверах под управлением ESXi 5.1. Существует приложение zeromq client-server, работающее между двумя виртуальными машинами. После запуска в течение 10-30 минут это приложение постоянно зависает из-за невозможности повторной передачи потерянного пакета.

Когда я запускаю ту же настройку по Ubuntu 12.04 (Linux 3.11), приложение никогда не сработает (UPDATE: также не работает 12.04, но занимает больше времени)

Если вы заметили ниже,сс"(статистика сокетов) показывает 1 потерянный пакет, sk_wmem_queued из 14110 (т. е. w14110) и высокий rto (120000).

State      Recv-Q Send-Q                                      Local Address:Port                                          Peer Address:Port

ESTAB      0      **12350**                                       192.168.2.122:41808                                        192.168.2.172:55550    

timer:(on,16sec,10) uid:1000 ino:35042 

sk:ffff880035bcb100 <->
         skmem:(r0,rb648720,t0,tb1164800,f2274,**w14110**,o0,bl0) ts sack cubic wscale:7,7 rto:120000 rtt:7.5/3 ato:40 mss:8948 cwnd:1 ssthresh:21 send 9.5Mbps **unacked:1 retrans:1/10 lost:1** rcv_rtt:1476 rcv_space:37621

Поскольку это произошло так последовательно, я смог захватить протокол TCP в wirehark. Я обнаружил, что потерянный пакет повторно передается и даже подтверждается TCP в другой ОС (порядковый номер указан в ACK), но отправитель, похоже, не понимает этот ACK и продолжает ретрансляцию.

MTU - 9000 на обеих виртуальных машинах и на пути по маршруту. Отправляемые пакеты имеют большой размер.

Как я сказал ранее, этого не происходит на Ubuntu 12.04 (ядро 3.11). Таким образом, я сделал diff для параметров конфигурации TCP (см. «Sysctl -a | grep tcp») между 14.04 и 12.04 и нашел следующие отличия.

Я также заметил, что net.ipv4.tcp_mtu_probing = 0 в обеих конфигурациях.

Левая сторона - 3,11, правая сторона - 3,13

<<net.ipv4.tcp_abc = 0
<<net.ipv4.tcp_cookie_size = 0
<<net.ipv4.tcp_dma_copybreak = 4096

14c11
<< net.ipv4.tcp_early_retrans = 2
---
>> net.ipv4.tcp_early_retrans = 3

17c14
<< net.ipv4.tcp_fastopen = 0
>> net.ipv4.tcp_fastopen = 1

20d16
<< net.ipv4.tcp_frto_response = 0
26,27c22
<< net.ipv4.tcp_max_orphans = 16384
<< net.ipv4.tcp_max_ssthresh = 0

>> net.ipv4.tcp_max_orphans = 4096
29,30c24,25
<< net.ipv4.tcp_max_tw_buckets = 16384
<< net.ipv4.tcp_mem = 94377 125837  188754

>> net.ipv4.tcp_max_tw_buckets = 4096
>> net.ipv4.tcp_mem = 23352 31138   46704
34a30
>> net.ipv4.tcp_notsent_lowat = -1

Мой вопрос к сетевым экспертам на этом форуме: Существуют ли какие-либо другие инструменты или опции для отладки, которые я могу установить / разрешить, чтобы понять, почему этот отказ повторной передачи TCP происходит так последовательно? Существуют ли какие-либо изменения в конфигурации, которые могут объяснить это странное поведение.

UPDATE (для тех, кто может столкнуться с подобной проблемой позже): я смог воспроизвести проблему и на 3.11, а затем смог уклониться от этой проблемы, снизив MTU.

О подобной проблеме сообщалось здесь https://serverfault.com/questions/488893/how-do-i-prevent-tcp-connection-freezes-over-an-openvpn-network, Приведенное здесь описание соответствует тому, что я видел:

«В какой-то момент с клиентами Ubuntu, однако, удаленный конец начинается   повторная передача одного и того же сегмента TCP снова и снова (с передачей   увеличение задержки между каждой повторной передачей). Клиент отправляет то, что   выглядит как действительный TCP ACK для каждой повторной передачи, но удаленный конец   по-прежнему продолжает передавать один и тот же сегмент TCP периодически ».

Может быть, связанная статья: https://blogs.kent.ac.uk/unseenit/2013/10/18/stalled-scp-and-hanging-tcp-connections/


2
2018-06-02 11:39


происхождения


Это может быть ошибка. Вы можете попробовать установить последнее ядро ​​mainline, чтобы узнать, не исчезла ли проблема. - bain
Ошибка также 3.14.0-031400! Может ли кто-нибудь дать мне пару upvotes, чтобы получить привилегии для добавления тегов и т. Д.? - SandeepJ
Последнее надежное ядро ​​из основной PPA 3,15-rc2 - bain
Не могли бы вы попытаться загрузить ваше ядро ​​12.04 (это работает) в 14.04? - bain
да, опубликует обновление после этого - SandeepJ


ответы:


Он заметил ту же проблему: ядро ​​Linux 3.2 на Ubuntu 12.04 работало без проблем, Linux 3.13 на Unbuntu 14.02 имел ту же проблему.

Я не уверен, что это действительно ошибка в ядре, для меня это больше похоже на проблему с выборочными ACK (SACK). Вы можете решить эту проблему, отключив TCP SACK с помощью:

sysctl net.ipv4.tcp_sack = 0

Это помогло решить эту проблему. В нашем случае клиенты с потерянными или удаленными соединениями (например, разные дата-центры, линии DSL) больше не могли загружать большие файлы. Примерно через несколько мегабайт загрузка HTTP-соединения застопорилась. TCDump показал много выборочных ACKS (SACK), переданных.

И да, загрузка 14.04 ядра в 14.04 тоже помогла.

Я думаю, мы должны открыть проблему в Ubuntu. Я просто не был уверен, что проблема возникает только из-за нашего оборудования сети / маршрутизатора, но, похоже, проблема в том, что TCP SACK ошибочен.


2
2017-12-21 12:22



Уве, это внутри виртуальной машины? Я сталкивался с проблемой vmware, и это наблюдалось другими. Смотрите здесь communities.vmware.com/message/2390611#2390611 - SandeepJ