TCP TIME_WAIT過多的解決方法
總結:
最合適的解決方案是增加更多的四元組數目,比如,伺服器監聽埠,或伺服器IP,讓伺服器能容納足夠多的TIME-WAIT狀態連線。在我們常見的網際網路架構中(NGINX反代跟NGINX,NGINX跟FPM,FPM跟redis、mysql、memcache等),減少TIME-WAIT狀態的TCP連線,最有效的是使用長連線,不要用短連線,尤其是負載均衡跟web伺服器之間。尤其是鏈家事件中的PHP連不上redis。
在服務端,不要啟用net.ipv4.tcp_tw_recycle,除非你能確保你的伺服器網路環境不是NAT。在服務端上啟用net.ipv4.tw_reuse對於連線進來的TCP連線來說,並沒有任何卵用。在客戶端(尤其是伺服器上,某服務以客戶端形式執行時,比如上面提到的nginx反代,連線著redis、mysql的FPM等等)上啟用net.ipv4.tcp_tw_reuse,還算稍微安全的解決TIME-WAIT的方案。
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無效
2. 線上環境 tw_recycle 不要開啟
伺服器處於NAT 負載後,或者客戶端處於NAT後(這是一定的事情,基本公司家庭網路都走NAT);
公網服務開啟就可能造成部分連線失敗,內網的話到時可以視情況開啟;
(分析:主機client1和client2通過NAT閘道器(1個ip地址)訪問serverN,由於timestamp時間為系統啟動到當前的時間,因此,client1和client2的timestamp不相同;根據上述syn包處理原始碼,在tcp_tw_recycle和tcp_timestamps同時開啟的條件下,timestamp大的主機訪問serverN成功,而timestmap小的主機訪問失敗)
像我所在公司對外服務都放在負載後面,負載會把timestamp 都給清空,好吧,就算你開啟也不起作用。
3. 伺服器TIME_WAIT 高怎麼辦
不像客戶端有埠限制,處理大量TIME_WAIT Linux已經優化很好了,每個處於TIME_WAIT 狀態下連線記憶體消耗很少,
而且也能通過tcp_max_tw_buckets = 262144 配置最大上限,現代機器一般也不缺這點記憶體。
參考部落格:
http://blog.sina.com.cn/s/blog_781b0c850100znjd.html
http://www.tuicool.com/articles/3eYRb2A
http://www.cnblogs.com/lulu/p/4149312.html