Linux

為什麼 nginx 在收到客戶端 FIN 後沒有立即關閉連接?

  • June 15, 2020

問題: 我們已經設置了一個 CDN 提供商作為我們靜態圖像文件伺服器的代理。幾個小時後,我們遇到了非常高的 TCP SYN 丟棄率和異常高的孤立連接數。

解決問題的觀察: 我擷取了 1.5 秒的伺服器流量並檢查了一些圖像下載。可疑的是,幾乎配置了預設值的 Nginx 正在以 ACK 而不是 FIN/ACK 來響應 CDN 伺服器的 FIN 數據包。在來自 nginx 的 ACK 之後,連接埠上整整一秒鐘都保持沉默,這意味著伺服器沒有進一步的發送。由於流量大,我無法捕捉超過 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 保持活動標頭。我不確定的分析是,來自 CDN 端的錯誤配置使其對每個圖像使用一個連接以及發送保持活動的標頭。它使 nginx 讓 TCP 保持活動狀態,並且 FIN 數據包僅由 ACK 響應。然後一種解決方法是將 nginx 保持活動超時減少到 1 秒。

問題:這個問題的確切原因是什麼?或者我應該改變什麼來解決這個問題?

在我檢查了請求的內容之後,nginx 的行為是由於 CDN 的行為造成的。因為 CDN 正在使用保持活動連接,並且 nginx 中保持活動連接的持續時間設置為 60 秒左右。當我將其減少到 15 秒時,情況恢復正常。

您要解決的問題是什麼?

孤立連接和“SYN 丟棄”並不是真正的問題。NGINX 很少,上次我看了,關心這些細節。

您添加了一個 CDN。並且那個 CDN 不是使用者。因此,它的行為不同。

您可能會用完池中的連接空間。增加那個。

請發布更具體的問題以獲得更多清晰度。

引用自:https://serverfault.com/questions/993021