У нас есть Windows Server 2012 R2, на котором наши веб-сайты размещаются в IIS. У нас также есть сервер Ubuntu 16.04, на котором работает Nginx 1.10.3 для проксирования входящих запросов на наш внутренний сервер Windows. Оба эти сервера работают как виртуальные машины на ESXi.
Мы заметили, что нашему серверу Windows иногда требуется слишком много времени для отправки SYN-ACK в ответ на входящие SYN.
Вот как выглядит вывод Windump на сервере Windows (как вы можете видеть, только через 63 секунды и 7 SYN, Windows отправила соответствующий SYN-ACK):
11:26:59.080471 IP 192.168.20.129.41784 > 192.168.20.2.80: Flags [S], seq 3338047317, win 29200, options [mss 1460,sackOK,TS val 60011765 ecr 0,nop,wscale 7], length 0
11:27:00.075553 IP 192.168.20.129.41784 > 192.168.20.2.80: Flags [S], seq 3338047317, win 29200, options [mss 1460,sackOK,TS val 60012015 ecr 0,nop,wscale 7], length 0
11:27:02.078881 IP 192.168.20.129.41784 > 192.168.20.2.80: Flags [S], seq 3338047317, win 29200, options [mss 1460,sackOK,TS val 60012516 ecr 0,nop,wscale 7], length 0
11:27:06.086875 IP 192.168.20.129.41784 > 192.168.20.2.80: Flags [S], seq 3338047317, win 29200, options [mss 1460,sackOK,TS val 60013518 ecr 0,nop,wscale 7], length 0
11:27:14.094838 IP 192.168.20.129.41784 > 192.168.20.2.80: Flags [S], seq 3338047317, win 29200, options [mss 1460,sackOK,TS val 60015520 ecr 0,nop,wscale 7], length 0
11:27:30.126966 IP 192.168.20.129.41784 > 192.168.20.2.80: Flags [S], seq 3338047317, win 29200, options [mss 1460,sackOK,TS val 60019528 ecr 0,nop,wscale 7], length 0
11:28:02.224731 IP 192.168.20.129.41784 > 192.168.20.2.80: Flags [S], seq 3338047317, win 29200, options [mss 1460,sackOK,TS val 60027552 ecr 0,nop,wscale 7], length 0
11:28:02.224789 IP 192.168.20.2.80 > 192.168.20.129.41784: Flags [S.], seq 2819099122, ack 3338047318, win 8192, options [mss 1460,nop,wscale 8,sackOK,TS val 215763098 ecr 60027552], length 0
11:28:02.225363 IP 192.168.20.129.41784 > 192.168.20.2.80: Flags [.], ack 1, win 229, options [nop,nop,TS val 60027552 ecr 215763098], length 0
11:28:02.225900 IP 192.168.20.129.41784 > 192.168.20.2.80: Flags [P.], seq 1:76, ack 1, win 229, options [nop,nop,TS val 60027552 ecr 215763098], length 75: HTTP: GET /ping?id=141 HTTP/1.1[!http]
11:28:02.248577 IP 192.168.20.2.80 > 192.168.20.129.41784: Flags [FP.], seq 1:224, ack 76, win 260, options [nop,nop,TS val 215763100 ecr 60027552], length 223: HTTP: HTTP/1.1 200 OK
11:28:02.253096 IP 192.168.20.129.41784 > 192.168.20.2.80: Flags [F.], seq 76, ack 225, win 237, options [nop,nop,TS val 60027559 ecr 215763100], length 0
11:28:02.253144 IP 192.168.20.2.80 > 192.168.20.129.41784: Flags [.], ack 77, win 260, options [nop,nop,TS val 215763101 ecr 60027559], length 0
Странно то, что если мы изменим исходный IP-адрес (через proxy_bind Nginx) или порт назначения (в IIS), время отклика значительно увеличится.
Как мы можем узнать, что вызывает такое поведение?
Обновление 1: Мы изменили параметр TcpTimedWaitDelay на 30 секунд, и сейчас ситуация намного лучше, но проблема все еще существует.
Обновление 2: Вот сумма состояний подключения, которые сообщает netstats:
64 CLOSE_WAIT
1371 ESTABLISHED
1 FIN_WAIT_1
51 LISTENING
3188 TIME_WAIT
Насколько мне известно, возможно, старый добрый Нэгл является пинать твои яйца Вот. Я бы порекомендовал вам тест выключите его, а также уменьшите внутренний счетчик тиков до ответа.
Это делается в реестре:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\{YOUR-NIC}
TCPNoDelay
со значением "1"TcpAckFrequency
со значением "1"TcpDelAckTicks
со значением '0' (Больше)Для их активации требуется перезагрузка. Вы можете проверить свои настройки с помощью Get-NetTCPSetting
.