踩坑内核参数tcp_tw_recycle
文章目錄
- 踩坑內核參數tcp_tw_recycle
 - 一、問題背景
 - 二、優化分析
 - 1.參數解釋
 - 2.原理分析及優化建議
 - (1)什么是TCP TIME-WAIT狀態:
 - (2)TIME-WAIT存在的作用及原因:
 - (3)開啟tcp_tw_recycle后為什么會造成網絡問題:
 - 現象一:延遲的出現
 - 現象二:沒有ACK回包
 
- (4) tcp_tw_recycle參數的移除
 
- 三、操作步驟
 
踩坑內核參數tcp_tw_recycle
一、問題背景
近期我們發現客戶生產環境出現了偶發性的502報錯,表現為點擊瀏覽器或APP頁面時會出現502錯誤,復現概率不高無明顯規律。
通過分析問題表現我們判斷可能是以下幾個問題導致:
- 容器ip重復導致的網絡時通時不通
 - iptables規則中存在reject規則,導致部分nat過程被拒絕
 - 內核參數tcp_tw_recycle開啟導致的tcp time-wait sockets快速回收
 
根據以上思路進行了問題排查,發現容器ip不存在重復現象,對比查看多主機iptables規則后并無異常,因此我們需要繼續驗證是否是由于生產環境物理機中開啟內核參數tcp_tw_recycle而導致的此問題。
我們在測試環境的虛擬機上同樣開啟了tcp_tw_recycle內核參數以求復現問題。開啟該內核參數后,進行了頁面訪問測試,并未復現502報錯異常。但通過對比開啟前的情況,我們發現開啟該參數后界面加載速度明顯變慢但可以正常訪問。因此我們認為該參數在開啟后對TCP網絡連接產生了影響,但由于測試環境與生產環境還是存在一定差異且該參數的開啟與關閉并不是一定會觸發網絡問題。隨后我們在生產環境中進行抓包,發現只有SYN包沒有回SYN和ACK包。這一抓包現象與開啟該參數會產生的現象吻合度非常高。因此建議關閉tcp_tw_recycle內核參數以避免此網絡問題的復現,并提供該內核參數的技術原理以供參考。
二、優化分析
1.參數解釋
這里我們引用linux手冊TCP協議的官方解釋。
原文:
tcp_tw_recycle (Boolean; default: disabled; since Linux 2.4)
Enable fast recycling of TIME_WAIT sockets. Enabling this option is not recommended since this causes problems when working with NAT (Network Address Translation).
直譯:
tcp_tw_recycle
啟用TIME-WAIT狀態sockets的快速回收,這個選項不推薦啟用。在NAT(Network Address Translation)網絡下,會導致大量的TCP連接建立錯誤。
2.原理分析及優化建議
(1)什么是TCP TIME-WAIT狀態:
首先我們需要理解什么是tcp time-wait狀態。簡單來講通信雙方建立TCP連接后,主動關閉連接的一方就會進入TIME_WAIT狀態,是在closed前的一個等待狀態,需要的等待時長為2MSL(max segment lifetime),目的是為了可靠且正常的關閉連接。
tcp連接狀態轉換圖:
(2)TIME-WAIT存在的作用及原因:
- 為實現TCP全雙工連接的可靠釋放,防止上一個TCP連接的延遲的數據包(發起關閉,但關閉沒完成),被接收后影響到新的TCP連接。
 - 當最后一個ACK丟失時,遠程連接進入LAST-ACK狀態,它可以確保遠程已經關閉當前TCP連接。如果沒有TIME-WAIT狀態,當遠程仍認為這個連接是有效的,則會繼續與其通訊,導致這個連接會被重新打開。當遠程收到一個SYN 時,會回復一個RST包,因為這SEQ不對,那么新的連接將無法建立成功,報錯終止。
 
(3)開啟tcp_tw_recycle后為什么會造成網絡問題:
根據官方解釋中一個簡短的描述:“Enabling this option is not recommended since this causes problems when working with NAT (Network Address Translation).”當中重點提示了如果在網絡鏈路中存在nat網絡不推薦啟用。
我們繼續分析開啟該參數會導致的網絡現象和原因:
現象一:延遲的出現
還是說回TIME-WAIT的作用,第一個作用是避免新的連接(不相關的)接收到重復的數據包。由于使用了時間戳,重復的數據包會因為timestamp過期而丟棄。第二個作用是確保遠程端是不是在LAST-ACK狀態,因為有可能丟ACK包丟。遠程端會重發FIN包,直到放棄(連接斷開),等到ACK包,收到RST包。如果 FIN包接及時收到,本地端依然是TIME-WAIT狀態,同時,ACK包也會發送出去。
當新的連接替換了TIME-WAIT的entry,新連接的SYN包會被忽略掉(得益于timestramps),也不會應答RST包,但會重傳FIN包。 FIN包將會收到一個RST包的應答(因為本地連接是SYN-SENT狀態),這會讓遠程端跳過LAST-ACK狀態。 最初的SYN包將會在1秒后重新發送,然后完成連接的建立。看起來沒有錯誤發生,只是延遲了一下。
現象狀態分析圖如下:
現象二:沒有ACK回包
TIME-WAIT的回收機制依賴于時間戳TIMESTAMP,這會影響到所有連接進來和連接出去的連接。Linux將會放棄所有來自遠程端的timestramp時間戳小于上次記錄的時間戳也是遠程端發來的的任何數據包。除非TIME-WAIT狀態已經過期。
當遠程端主機HOST處于NAT網絡中時,時間戳在一分鐘之內(MSL時間間隔)將禁止了NAT網絡后面,除了這臺主機以外的其他任何主機連接,因為他們都有各自CPU CLOCK,各自的時間戳。無法保證經過 NAT 轉換后的客戶端 TCP 請求 Header 中的 Timestamp 值嚴格遞增;(因為各客戶端時間可能不同步,很難保證他們的 TCP 請求的 timestamp 嚴格遞增)
 而 kernel 的 PASW 機制要求所有來自同一個 Host IP 的 TCP 包 timestamp 必須是遞增的,當收到的 timestamp 變小時,會認為這是一個過期的數據包,將其丟棄。這會導致很多疑難雜癥,很難去排查。
同時在nat環境中會出現時間戳錯亂的情況,后面的數據包就被丟棄了,具體的表現通常是客戶端明明發送的SYN,但服務端就是不響應ACK(與生產環境中抓包現象一致)。因為NAT設備將數據包的源IP地址都改成了一個地址(或者少量的IP地址),但是卻基本上不修改TCP包的時間戳,則會導致時間戳混亂。建議:如果網絡鏈路中存在nat,盡量關閉快速回收,以免發生由于時間戳混亂導致的SYN拒絕問題。
(4) tcp_tw_recycle參數的移除
根據linux內核源代碼樹的一個commit,可以看到tcp_tw_recycle參數已經在linux 4.12移除。
原文及鏈接:net.ipv4.tcp_tw_recycle has been removed from Linux?4.12.
The tcp_tw_recycle was already broken for connections behind NAT, since the per-destination timestamp is not monotonically increasing for multiple machines behind a single destination address.After the randomization of TCP timestamp offsets in commit 8a5bd45f6616 (tcp: randomize tcp timestamp offsets for each connection), the tcp_tw_recycle is broken for all types of connections for the same reason: the timestamps received from a single machine is not monotonically increasing, anymore.Remove tcp_tw_recycle, since it is not functional. Also, remove the PAWSPassive SNMP counter since it is only used for tcp_tw_recycle, and simplify tcp_v4_route_req and tcp_v6_route_req since the strict argument is only set when tcp_tw_recycle is enabled.三、操作步驟
#查詢內核參數值 sysctl -a --pattern=tcp_tw_recycle #設置內核參數 sysctl -w net.ipv4.tcp_tw_recycle=0參考鏈接:
 https://imroc.io/posts/kubernetes/lost-packets-once-enable-tcp-tw-recycle/
 https://support.hpe.com/hpesc/public/docDisplay?docId=emr_na-c00782457
 https://coolshell.cn/articles/18654.html
 https://www.cnblogs.com/sunsky303/p/12818009.html
總結
以上是生活随笔為你收集整理的踩坑内核参数tcp_tw_recycle的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: vcpkg下载mysql库_VCpkg
 - 下一篇: CRF模型详解