linux TIME_WAIT 相關參數:
net.ipv4.tcp_tw_reuse = 0 表示開啟重用。允許將TIME-WAIT sockets重新用於新的TCP連接,默認為0,表示關閉 net.ipv4.tcp_tw_recycle = 0 表示開啟TCP連接中TIME-WAIT sockets的快速回收,默認為0,表示關閉 net.ipv4.tcp_fin_timeout = 60 表示如果套接字由本端要求關閉,這個參數決定了它保持在FIN-WAIT-2狀態的時間
注意:
- 不像Windows 可以修改注冊表修改2MSL 的值,linux 需要修改內核宏定義重新編譯,tcp_fin_timeout 不是2MSL 而是Fin-WAIT-2狀態超時時間.
- tcp_tw_reuse 和 SO_REUSEADDR 是兩個完全不同的東西
SO_REUSEADDR 允許同時綁定 127.0.0.1 和 0.0.0.0 同一個端口; SO_RESUSEPORT linux 3.7才支持,用於綁定相同ip:port,像nginx 那樣 fork方式也能實現
1. tw_reuse,tw_recycle 必須在客戶端和服務端 timestamps 開啟時才管用(默認打開)
2. tw_reuse 只對客戶端起作用,開啟后客戶端在1s內回收
3. tw_recycle 對客戶端和服務器同時起作用,開啟后在 3.5*RTO 內回收,RTO 200ms~ 120s 具體時間視網絡狀況。
內網狀況比tw_reuse 稍快,公網尤其移動網絡大多要比tw_reuse 慢,優點就是能夠回收服務端的TIME_WAIT數量
對於客戶端
1. 作為客戶端因為有端口65535問題,TIME_OUT過多直接影響處理能力,打開tw_reuse 即可解決,不建議同時打開tw_recycle,幫助不大;
2. tw_reuse 幫助客戶端1s完成連接回收,基本可實現單機6w/s短連接請求,需要再高就增加IP數量;
3. 如果內網壓測場景,且客戶端不需要接收連接,同時 tw_recycle 會有一點點好處;
4. 業務上也可以設計由服務端主動關閉連接。
對於服務端
1. 打開tw_reuse無效, 如果在server中用了HttpClient,那么就可以使用。
2. 線上環境 tw_recycle 不建議打開
服務器處於NAT 負載后,或者客戶端處於NAT后(基本公司家庭網絡基本都走NAT);
公網服務打開就可能造成部分連接失敗,內網的話到時可以視情況打開;
像我所在公司對外服務都放在負載后面,負載會把 timestamp 都給清空,就算你打開也不起作用。
3. 服務器TIME_WAIT 高怎么辦
不像客戶端有端口限制,處理大量TIME_WAIT Linux已經優化很好了,每個處於TIME_WAIT 狀態下連接內存消耗很少。
下面像我們一台每秒峰值1w請求的 http 短連接服務,長期處於tw_buckets 溢出狀態,
tw_socket_TCP 占用70M, 因為業務簡單服務占用CPU 200% 運行很穩定。
slabtop
262230 251461 95% 0.25K 17482 15 69928K tw_sock_TCP
ss -s Total: 259 (kernel 494) TCP: 262419 (estab 113, closed 262143, orphaned 156, synrecv 0, timewait 262143/0), ports 80 Transport Total IP IPv6 * 494 - - RAW 1 1 0 UDP 0 0 0 TCP 276 276 0 INET 277 277 0 FRAG 0 0 0
唯一不爽的就是:
系統日志中overflow 錯誤一直再刷屏,也許該buckets 調大一下了
TCP: time wait bucket table overflow
TCP: time wait bucket table overflow
TCP: time wait bucket table overflow
TCP: time wait bucket table overflow
TCP: time wait bucket table overflow
通過tcp_max_tw_buckets = 262144 配置最大上限,現代機器一般也不缺這點內存。
5. 業務上也可以設計由客戶端主動關閉連接
原理分析
1. MSL 由來
發起連接關閉方回復最后一個fin 的ack,為避免對方ack 收不到、重發的或還在中間路由上的fin 把新連接給丟掉了,等個2MSL(linux 默認2min)。
也就是連接有誰關閉的那一方有time_wait問題,被關那方無此問題。
2. reuse、recycle
通過timestamp的遞增性來區分是否新連接,新連接的timestamp更大,那么保證小的timestamp的 fin 不會fin掉新連接,不用等2MSL。
3. reuse
通過timestamp 遞增性,客戶端、服務器能夠處理outofbind fin包
4. recycle
對於服務端,同一個src ip,可能會是NAT后很多機器,這些機器timestamp遞增性無可保證,服務器會拒絕非遞增請求連接。
參考:
Coping with the TCP TIME-WAITstate on busy Linux servers
tcp短連接TIME_WAIT問題解決方法大全(3)——tcp_tw_recycle
tcp短連接TIME_WAIT問題解決方法大全(4)——tcp_tw_reuse
tcp_tw_recycle和tcp_timestamps導致connect失敗問題