Назад | Перейти на главную страницу

Почему nginx не закрывает соединение сразу после получения FIN клиента?

Проблема: Мы настроили поставщика CDN в качестве прокси для нашего файлового сервера статических изображений. Через несколько часов мы столкнулись с критически высоким коэффициентом падений TCP SYN и аномально большим количеством потерянных соединений.

Наблюдения для решения проблемы: Я захватил 1,5 секунды трафика сервера и проверил загрузку некоторых изображений. Подозрительно то, что nginx, который почти настроен со значениями по умолчанию, отвечает на пакет FIN сервера CDN с помощью ACK вместо FIN / ACK. После ACK от nginx на порту подключения на секунду тишина, что означает, что серверу больше нечего отправлять. Я не мог снимать больше 1,5 секунд из-за большого трафика.

Вот краткое изложение примера TCP-соединения:

No.     Time        Source      Destination Proto   Length and Info 
20      0.004281671 [CDN IP]    [NGINX IP]  TCP     74  20200 → 443 [SYN] Seq=0 Win=28400 Len=0 MSS=1420 SACK_PERM=1 TSval=2822189024 TSecr=0 WS=1024
21      0.004333161 [NGINX IP]  [CDN IP]    TCP     74  443 → 20200 [SYN, ACK] Seq=0 Ack=1 Win=28960 Len=0 MSS=1460 SACK_PERM=1 TSval=2611883387 TSecr=2822189024 WS=128
372     0.125341624 [CDN IP]    [NGINX IP]  TCP     66  20200 → 443 [ACK] Seq=1 Ack=1 Win=28672 Len=0 TSval=2822189148 TSecr=2611883387
373     0.125357371 [CDN IP]    [NGINX IP]  TLSv1.2 287 Client Hello
374     0.125367976 [NGINX IP]  [CDN IP]    TCP     66  443 → 20200 [ACK] Seq=1 Ack=222 Win=30080 Len=0 TSval=2611883417 TSecr=2822189149
392     0.127328681 [NGINX IP]  [CDN IP]    TLSv1.2 2882    Server Hello, Certificate
393     0.127339623 [NGINX IP]  [CDN IP]    TLSv1.2 233 Server Key Exchange, Server Hello Done
645     0.244326565 [CDN IP]    [NGINX IP]  TCP     66  20200 → 443 [ACK] Seq=222 Ack=2984 Win=34816 Len=0 TSval=2822189267 TSecr=2611883418
646     0.244353033 [CDN IP]    [NGINX IP]  TLSv1.2 192 Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message
647     0.244630520 [NGINX IP]  [CDN IP]    TLSv1.2 324 New Session Ticket, Change Cipher Spec, Encrypted Handshake Message
1121    0.360323576 [CDN IP]    [NGINX IP]  TLSv1.2 1496    Application Data    
1122    0.360373767 [NGINX IP]  [CDN IP]    TCP     66  443 → 20200 [ACK] Seq=3242 Ack=1778 Win=33024 Len=0 TSval=2611883476 TSecr=2822189383
1123    0.360539425 [NGINX IP]  [CDN IP]    TLSv1.2 392 Application Data    
1124    0.360614290 [NGINX IP]  [CDN IP]    TLSv1.2 97  Encrypted Alert 
1554    0.477351117 [CDN IP]    [NGINX IP]  TCP     78  [TCP Window Update] 20200 → 443 [ACK] Seq=1778 Ack=3242 Win=40960 Len=0 TSval=2822189500 TSecr=2611883447 SLE=3568 SRE=3600
1555    0.477369934 [CDN IP]    [NGINX IP]  TCP     66  20200 → 443 [ACK] Seq=1778 Ack=3600 Win=43008 Len=0 TSval=2822189501 TSecr=2611883476
1596    0.505356016 [CDN IP]    [NGINX IP]  TCP     66  20200 → 443 [FIN, ACK] Seq=1778 Ack=3600 Win=43008 Len=0 TSval=2822189530 TSecr=2611883476
1597    0.505368886 [NGINX IP]  [CDN IP]    TCP     66  443 → 20200 [ACK] Seq=3600 Ack=1779 Win=33024 Len=0 TSval=2611883512 TSecr=2822189530

Также я предполагаю, что сервер CDN использует заголовок HTTP keep alive. Мой неуверенный анализ состоит в том, что неправильная конфигурация со стороны CDN заставляет использовать одно соединение для каждого изображения, а также отправлять заголовки keep-alive. Это заставляет nginx поддерживать активность TCP, а пакет FIN просто отвечает ACK. Тогда обходным путем было бы уменьшить тайм-аут nginx keep-alive до 1 секунды.

Вопрос: Что могло бы быть точной причиной этой проблемы? Или что мне изменить, чтобы решить эту проблему?

Что проблема вы пытаетесь решить?

Потерянные соединения и "отбросы SYN" на самом деле не проблема. В последний раз, когда я смотрел, NGINX мало заботится об этих деталях.

вы добавили CDN. и что CDN не пользователь. как таковой он ведет себя иначе.

у вас может закончиться место для подключения в пуле. увеличить это.

пожалуйста, задавайте более конкретные вопросы для большей ясности.

После того, как я проверил содержимое запросов, поведение nginx было обусловлено поведением CDN. Поскольку CDN использовал соединения keep alive, а продолжительность соединений keep alive в nginx была установлена ​​на что-то большее, например 60 с. Когда я уменьшил это значение до 15 секунд, ситуация вернулась в норму.