Начальное рукопожатие TCP не завершено (ACK отсутствует)
Меня раздражает следующий сценарий:
Я запускаю приложение MVC на веб-сервере IIS 10. При вызове URI требуется около 10 секунд, пока приложение не начнет вызываться (время ожидания). Не имея реального объяснения происходящему холостому ходу, я начал копать глубже, используя wireshark, и наткнулся на следующее явление:
Начальное TCP рукопожатие не завершено (отсутствует ACK)
- Клиент -> Сервер (SYN)
- Сервер -> Клиент (SYN, ACK)
- Клиент -> Сервер (ACK никогда не достигает сервера)
Примечание. Топология описана ниже. Клиент перенаправляется на Server2 после первого запроса. Клиент -> Шлюз -> Маршрутизатор -> Сервер1 -> Сервер2
Я использовал wireshark как на стороне клиента, так и на стороне сервера. Сервер повторно отправляет кортеж SYN, ACK два раза, после примерно 10 секунд IDLE, тем не менее, соединение установлено. Если посмотреть на соответствующий RFC, это нормальное поведение (ACK отправляется клиентом косвенно при отправке данных). ACK никогда не достигает маршрутизатора, так где он может быть потерян? И почему теряется КАЖДЫЙ раз? Может ли быть какая-то настройка роутера (Mikrotik), например No-ACK? Является ли пропущенный ACK причиной задержки 10s IDLE?
РЕДАКТИРОВАТЬ:
Я редактировал топологию выше. Вы найдете следы проволочной акулы ниже:
Благодаря процессу анонимизации в TraceWrangler, IP-адреса варьируются от трассировки к трассе следующим образом:
Client IP: 192.168.248.249 <=> 172.23.147.181 <=> 192.168.201.209 <=> 10.206.108.221
Router IP: 10.194.30.227 <=> 172.17.84.111
Server1 IP: 172.31.124.208 <=> 10.100.24.4
Server2 IP: 172.20.78.56 <=> 192.168.204.149
Вы можете использовать следующие фильтры, чтобы получить четкое представление о первоначальном рукопожатии:
Filter Client: (((ip.dst ==192.168.248.249) && (ip.src ==10.194.30.227)) || ((ip.dst ==10.194.30.227) && (ip.src ==192.168.248.249))) && (tcp.flags.syn==1 ) || (tcp.flags == 0x0010 && tcp.seq==1 && tcp.ack==1)
Filter Router: (tcp.flags.syn==1 ) || (tcp.flags == 0x0010 && tcp.seq==1 && tcp.ack==1)
Filter Server1: (((ip.dst ==172.31.124.208) && (ip.src ==192.168.201.209)) || ((ip.dst ==192.168.201.209) && (ip.src ==172.31.124.208)) || ((ip.dst ==172.31.124.208) && (ip.src ==172.20.78.56)) || ((ip.dst ==172.20.78.56) && (ip.src ==172.31.124.208))) && (tcp.flags.syn==1 ) || (tcp.flags == 0x0010 && tcp.seq==1 && tcp.ack==1)
Filter Server2: (((ip.dst ==10.100.24.4) && (ip.src ==10.206.108.221)) || ((ip.dst ==10.206.108.221) && (ip.src ==10.100.24.4)) || ((ip.dst ==10.100.24.4) && (ip.src ==192.168.204.149)) || ((ip.dst ==192.168.204.149) &&(ip.src ==10.100.24.4))) && (tcp.flags.syn==1 ) || (tcp.flags == 0x0010 && tcp.seq==1 && tcp.ack==1)
1 ответ
Вы не поверите, но проблема тем временем была решена, я не очень понимаю, почему следующее изменение в RouterOS гарантирует, что ACK больше не теряется, и приложение загружается в спешке, но я очень рад этому: в списках маршрутов RouterOS IP-адрес шлюза вводился как IP-адрес, а не как имя интерфейса / DNS-имя.
У вас есть объяснение этой проблемы? Перевод / поиск занимает так много секунд, а ACK тем временем игнорируется? У меня всегда было чувство, что это должно быть проблемой в RouterOS, но я не знал, как ее отследить. Какое счастливое совпадение, что наш админ играл с таблицами роутера и попросил меня снова проверить время загрузки. Может ли это быть единственным изменением? Я смог подтвердить в Wireshark, что ACK больше не теряется.
РЕДАКТИРОВАТЬ:
Я экспортировал настройки IP-маршрута ниже, чтобы увидеть различия в маршруте:
- Работа: добавить расстояние =1 dst-адрес =33.2.1.0/24 шлюза =33.2.4.1 pref-src=33.2.4.211
- Старое состояние: добавить расстояние =1 dst-адрес =33.2.1.0/24 шлюза =ETH2 pref-src=33.2.4.211
Шлюз явно не определен в списке адресов, только маршрутизатор:
- Адрес: 33.2.4.211/24 | Сеть:33.2.4.0 | Интерфейс: ETH2
Итак, что происходит технически, и откуда происходят задержки и пропущенные ACK?