一、為什么TIME_WAIT等待的時間是2MSL?
MSL:報文最大生存時間
我們要知道TCP報文是基于IP協議生存的,而在IP頭中有一個TTL(經過路由跳數),當TTL為0使,數據報被丟失,同時發送ICMP報文通知主機
因此MSL的時間應該大于等于TTL消耗為0的時間(Linux設置MSL=30秒)
我們再來說一說為什么TIME_WAIT為什么是2MSL?
2MSL是從客戶端收到FIN發送ACK開始計時的
舉個例子:當客戶端主動關閉連接,而服務端沒有收到ACK報文,這時我們進行超時重傳,服務端再次發送一個FIN,而客戶端收到FIN后,會再次發送ACK報文,而這個時間剛好是2MSL。(因此2MSL相當于為至少可以丟失一次報文)
定義在Linux內核代碼里的名稱為TCP_TIMEWAIT_LEN:
#define TCP_TIMEWAIT_LEN (60*HZ)
若要修改TIME_WAIT的時間長度,只能修改Linux內核代碼里TCP_TIMEWAIT_LEN的值,并重新編譯Linux內核
二、為什么需要TIME_WAIT狀態
- 防止歷史連接中的數據,被后面相同四元組的連接錯誤的接收
-
保證【被動關閉連接】的一方,能被正確的關閉
三、TIME_WAIT過多有什么危害?
- 第一是占用系統資源,比如文件描述符、內存資源、CPU資源,線程資源等
- 第二是占用端口資源,端口資源也是有限的
四、服務器出現大量TIME_WAIT狀態的原因有哪些?
- HTTP沒有使用長連接
? ? ? ? 當服務器出現大量的TIME_WAIT狀態連接的時候,可以排查下是否客戶端和服務端都開啟了HTTP Keep-Alive,因為任意一方沒有開啟HTTP Keep-Alive,都會導致服務端在處理完一個HTTP請求后,主動關閉連接,此時服務端上就會出現大量的TIME_WAIT狀態的連接
- HTTP長連接超時
? ? ? ? 如果客戶端在完成一個HTTP請求后,在長連接超時時間內沒有再發起新的請求,定時器的時間一到,nginx就會觸發回調函數來關閉該連接,那么此時服務端上就會出現TIME_WAIT狀態的連接
- HTTP長連接的請求數量達到上限
? ? ? ? 如果長連接的請求數量達到上限,則nginx會主動關閉這個長連接,那么此時服務端上就會出現TIME_WAIT狀態的連接