0. 手把手教你作中間件、高性能服務器、分佈式存儲技術交流羣nginx
手把手教你作中間件、高性能服務器、分佈式存儲等(redis、memcache、nginx、大容量redis pika、rocksdb、mongodb、wiredtiger存儲引擎、高性能代理中間件),git地址以下:git
git地址:https://github.com/y123456yz/middleware_development_learninggithub
1. time_wait狀態產生條件redis
只有在正常四次揮手關閉鏈接的狀況下,在主動關閉鏈接的一方會出現一段時間的time_wait。若是啓用了快速回收功能,回收時間和網絡延遲情況有關,正常狀況下小於1s,若是沒有開啓time_wait快速回收功能,則time_wait回收時間默認60s。mongodb
三次揮手過程(FIN+ACK, FIN+ACK,ACK)的狀況,例如殺掉一段進程,第一個發送FIN+ACK的一端也會產生time_wait。服務器
2. Time_wait狀態相關參數說明網絡
TCP中有和time_wait狀態相關的參數有如下四個:socket
tcp_tw_recycletcp |
表示開啓TCP鏈接中time_wait的快速回收功能,默認爲0,表示關閉;生效前提是必須啓用本端和對端tcp_timestamps配置。分佈式 |
tcp_timestamps |
時間戳選項,只有在該選項置1的時候tcp_tw_recycle纔會生效。 |
tcp_max_tw_buckets |
表示系統同時保持time_wait的最大數量,若是超過這個量,time_wait將打印警告信息。超限的時候後面產生的time_wait直接不處理,釋放資源。注意:是新的鏈接直接釋放資源,老的鏈接仍是處於time_wait狀態。 |
Tcp_tw_reuse |
客戶端大量time_wait狀態存在時,端口被佔用,當有新的鏈接,若是沒有可用端口,則會鏈接失敗。啓用該功能後,能夠複用time_wait狀態的鏈接。客戶端tcp_tw_reuse生效前提是啓用本端和對端tcp_timestamp。
Tcp_tw_reuse端口重用功能通常只針對客戶端,由於服務端通常都是監聽固定端口,端口數是固定的,端口不會用完。而客戶端每次鏈接端口通常都是由協議棧自動分配。 |
3. Time_wait快速回收
Time_wait快速回收功能生效前提:啓用tcp_tw_recycle,並啓動本端和對端tcp_timestamps配置。啓用timestamps功能時,報文中會攜帶時間戳選項信息,抓包以下:
若是啓用了tcp_tw_recycle和tcp_timestamps,若是接收報文四層選項字段帶有時間戳信息,則會對時間戳進行檢查,對不知足條件的包會直接丟棄,可能會形成客戶端鏈接創建不成功。例如網絡路由信息反覆變化,移動cmwap網絡發來的包的時間戳亂跳,同一局域網經過路由器作NAT訪問服務器(由於作NAT後,源IP就變爲路由器的IP了,若是局域網內各個電腦系統時間不一致,則會出現)等狀況有可能會出現部分鏈接異常。緣由是tcp_tw_recycle/tcp_timestamps以及對端tcp_timestamps都開啓的條件下,60s內同一源ip主機的socket connect請求中的timestamp必須是遞增的。不一樣主機通過路由器作NAT後,報文的源IP地址就變爲路由器的IP地址了。
Time_wait狀態生成及快速回收相關代碼:
開啓timestamps引發的丟包相關源碼以下:
4. 客戶端端口重用
啓用tcp_tw_reuse,並啓動本端和對端tcp_timestamps配置。
5. 大量timewait對客戶端、服務端影響
因爲服務端只佔用監聽端口,所以不存在端口用完的現象。服務端大量time_wait惟一影響是:資源不釋放,內存沒法回收。
6. 測試驗證
本次測試結果採用sysbench.short來壓測cobar來驗證,客戶端物理設備和服務端物理設備的ip_local_port_range(1024~65000)和tcp_max_tw_buckets(81920)參數都是默認值,測試結果以下:
Cobar服務器time_wait超限的狀況下,客戶端sysbench壓測結果基本不受影響,以下:
從上面測試能夠看出,服務端time_wait不會影響客戶端建鏈,只是佔用內存。若是是客戶端出現大量time_wait狀態,此時端口用完,則沒法創建鏈接。以上測試結論符合理論、代碼分析。
7. 三種解決time_wait方法總結
|
Time_wait快速回收 |
端口重用 |
限制Tcp_max_tw_buckets |
配置方法 |
在須要進行time_wait快速回收的一端進行一下配置: tcp_tw_recycle:1 本端tcp_timestamps:1 對端tcp_timestamps:1 |
在須要進行time_wait快速回收的一端進行一下配置: tcp_tw_reuse:1 本端tcp_timestamps:1 對端tcp_timestamps:1 |
配置Tcp_max_tw_buckets 的值在60000如下。例如配置爲30000 |
反作用 |
在某些狀況下可能引發用戶建鏈接失敗(例如須要直接返回給用戶信息的服務器) 比較暴力,不符合TCP協議規範 |
在某些狀況下可能引發用戶建鏈接失敗(例如須要直接返回給用戶信息的服務器) 部署複雜,須要同時改服務端,而服務端比較多。 服務器時間戳會帶出IDC,通過中間各類網絡設備,尤爲是運營商的無線設備等,若是某個設備對時戳有校驗,則會產生丟包問題。 |
比較暴力,不符合TCP協議規範 應急的處理,立竿見影。 建議這種。 |