tcp timewait closewait 過多情況

TIMEWAIT作用

  1. 爲實現TCP全雙工連接的可靠釋放[最後一個ACK丟失了,被動關閉一方會重發它的FIN,主動關閉一方必須維持一個有效狀態信息(TIMEWAIT狀態下維持),以便能夠重發ACK,否則被動一方會認爲有錯誤產生]
  2. 保證在下一個人使用的IP地址與端口與先前的完全相同的情況下,上一個殘留的數據包,不會被下一個人接收到(time_wait持續等待時間爲2msl,確保數據丟失成功)。

TIMEWAIT CLOSE_WAIT什麼時候過多

如果你的程序設計爲服務器主動關閉,那麼你纔有可能需要關注這個TIMEWAIT狀態過多的問題。
1.在生產過程中,如果服務器使用短連接,那麼完成一次請求後會主動斷開連接,就會造成大量time_wait狀態。因此我們常常在系統中會採用長連接,減少建立連接的消耗,同時也減少TIME_WAIT的產生,
2.但實際上即使使用長連接配置不當時,當TIME_WAIT的生產速度遠大於其消耗速度時,系統仍然會累計大量的TIME_WAIT狀態的連接。TIME_WAIT狀態連接過多就會造成一些問題。如果客戶端的TIME_WAIT連接過多,同時它還在不斷產生,將會導致客戶端端口耗盡,新的端口分配不出來,出現錯誤。如果服務器端的TIME_WAIT連接過多,可能會導致客戶端的請求連接失敗,這在接下來舉例說明。

如果你的服務器設計爲被動關閉,那麼你首先要關注的是CLOSE_WAIT
close_wait 按照正常操作的話應該很短暫的一個狀態,接收到客戶端的fin包並且回覆客戶端ack之後,會繼續發送fin包告知客戶端關閉關閉連接,之後遷移到Last_ACK狀態。但是close_wait過多隻能說明沒有遷移到Last_ACK,也就是服務端是否發送fin包,只有發送fin包纔會發生遷移,所以問題定位在是否發送fin包。fin包的底層實現其實就是調用socket的close方法,這裏的問題出在沒有執行close方法。說明服務端socket忙於讀寫。

CLOSEWAIT過多解決辦法

基本的思想就是要檢測出對方已經關閉的socket,然後關閉它。
1.代碼需要判斷socket,一旦read返回0,斷開連接,read返回負,檢查一下errno,如果不是AGAIN(表示現在沒有數據稍後重新讀取),也斷開連接。
2.給每一個socket設置一個時間戳last_update,每接收或者是發送成功數據,就用當前時間更新這個時間戳。定期檢查所有的時間戳,如果時間戳與當前時間差值超過一定的閾值,就關閉這個socket。
3.使用一個Heart-Beat線程,定期向socket發送指定格式的心跳數據包,如果接收到對方的RST報文,說明對方已經關閉了socket,那麼我們也關閉這個socket。
4.設置SO_KEEPALIVE選項,並修改內核參數

TIMEWAIT過多解決辦法

讓服務器能夠快速回收和重用那些TIME_WAIT的資源這個可以通過改變內核配置做到

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章