Приложение застряло в ретрансляции TCP

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

Когда я запускаю ту же настройку через Ubuntu 12.04 (Linux 3.11), приложение никогда не завершается с ошибкой (ОБНОВЛЕНИЕ: также происходит сбой 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 в wireshark. Я обнаружил, что потерянный пакет действительно повторно передается и даже подтверждается TCP в другой ОС (порядковый номер виден в ACK), но отправитель, похоже, не понимает этот ACK и продолжает повторную передачу.

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

Как я уже говорил ранее, этого не происходит в Ubuntu 12.04 (ядро 3.11). Поэтому я провел различие по параметрам конфигурации 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 происходит так последовательно? Есть ли какие-либо изменения конфигурации, которые могут объяснить это странное поведение?

ОБНОВЛЕНИЕ (для тех, кто может столкнуться с подобной проблемой позже): я смог воспроизвести проблему и на 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
задан 13 April 2017 в 15:14

1 ответ

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

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

sysctl net.ipv4.tcp_sack=0

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

И да, загружая 12,04 ядер в 14,04 помог, также.

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

2
ответ дан 13 April 2017 в 15:14

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

Похожие вопросы: