服務端 tcp 丟失SYN/ACK 問題排查

[toc]html

總覽

與某公司對接, 發現有 10% 的超時狀況. tcp在咱們服務器發現, 有大量 SYN 包重傳的狀況, 並且只有 SYN包纔會重傳, 不少包重傳失敗, 有一些包重傳也會成功(注意 Retransmission):nginx

163	2017-12-20 13:27:41.125680	xxx.xxx.xxx.xxx	xxx.xxx.xxx.xxx	TCP	74	[TCP Retransmission] 60671 → 80 [SYN] Seq=0 Win=14600 Len=0 MSS=1460 SACK_PERM=1 TSval=2897178400 TSecr=0 WS=128

最終經過在對方服務端 nginx 和 後臺服務器關閉net.ipv4.tcp_tw_recycle功能解決.後端

排查過程

因之前沒抓過包, 被同事笑話了一番. 週末買了一本看完<Wireshark網絡分析就這麼簡單()>, 抓住這個機會實戰一下.服務器

讓對方分別在 nginx 和 後端服務器上抓了包. 顯示, nginx 上請求包和咱們機器上抓包現象相同. 可是 nginx 到 後端服務器的包都正常. 也就是說, nginx 沒有及時處理TCP鏈接請求.網絡

排查了一下nginx機器負載, 以及基本配置都沒有問題. 既然只有 SYN 類型包重傳, 現象很明顯, 就Google了一下. 找到這個帖子: 爲何服務端不回覆 SYN/ACK. 問題和咱們的如出一轍. 可是題主給出的解決方法存疑. 並且沒有給出爲何. 我注意到了帖子中lav的答案, 可能和net.ipv4.tcp_tw_recycle參數相關. 通過查看, 對方果真開啓了這個參數.tcp

度娘了一下這個參數, 發現這麼一段話(連接:tcp_tw_reuse、tcp_tw_recycle 使用場景及注意事項):code

對於服務端
1. 打開tw_reuse無效

2. 線上環境 tw_recycle 不要打開

   服務器處於NAT 負載後,或者客戶端處於NAT後(這是必定的事情,基本公司家庭網絡都走NAT);

 公網服務打開就可能形成部分鏈接失敗,內網的話到時能夠視狀況打開;

   像我所在公司對外服務都放在負載後面,負載會把timestamp 都給清空,好吧,就算你打開也不起做用
4. recycle

    對於服務端,同一個src ip,可能會是NAT後不少機器,這些機器timestamp遞增性無可保證,服務器會拒絕非遞增請求鏈接。

結論

因對方開啓了net.ipv4.tcp_tw_recycle參數, 這個參數會對同一個請求 IP 按照時間戳增續處理, 凡是小於上次時間戳的連接請求, 都被認爲是重傳包而丟棄. 咱們後臺服務器通過同一個 NAT 訪問對方 nginx, 出口IP是一個, 後臺服務器訪問對方nginx, 請求包裏面的 timestamp 可能會有差別. 致使 timestamp 落後的包被對方丟棄.server

解決方法

在對方服務端 nginx 和 後端服務器 把net.ipv4.tcp_tw_recycle參數關閉便可.htm

相關文章
相關標籤/搜索