TCP WAIT狀態及其對繁忙的伺服器的影響

2021-05-23 00:54:20 字數 2243 閱讀 3133

tcp有乙個time—wait狀態.通常有2分鐘。在乙個繁忙的**,2分鐘常常有數千個訪問請求.假設伺服器a的處理能力比b大兩倍,但伺服器a有數千個time~wait狀態.那麼伺服器b將在這2分鐘內承受巨大的壓力.

下面我來解釋一下 time_wait 狀態:

msl(最大分段生存期)指明tcp報文在internet上最長生存時間,每個具體的tcp實現都必須選擇乙個確定的msl值。rfc 1122建議是2分鐘。

time_wait 狀態最大保持時間是2 * msl,也就是1-4分鐘。 ip頭部有乙個ttl,最大值255。儘管ttl的單位不是秒(根本和時間無關),我們仍需 假設,ttl為255的tcp報文在internet上生存時間不能超過msl。 tcp報文在傳送過程中可能因為路由故障被迫緩衝延遲、選擇非最優路徑等等,結果傳送方tcp機制開始超時重傳。前乙個tcp報文可以稱為"漫遊tcp重複報文",後乙個tcp報文可以稱為"超時重傳tcp重複報文",作為面向連線的可靠協議,tcp實現必須正確處理這種重複報文,因為二者可能最終都到達。

乙個通常的tcp連線終止可以用圖描述如下:

當乙個socket關閉的時候,是通過兩端互發資訊的四次握手過程完成的,當一端呼叫close()時,就說明本端沒有資料再要傳送了。這好似看來在握手完成以後,socket就都應該處於關閉closed狀態了。但這有兩個問題,

第一:我們沒有任何機制保證最後的乙個ack能夠正常送達

第二:網路上仍然有可能有殘餘的資料報(wandering duplicates,或老的重複資料報),我們也必須能夠正常處理。

假設最後乙個ack丟失了,伺服器會重發它傳送的最後乙個fin,所以客戶端必須維持乙個狀態資訊,以便能夠重發ack;如果不維持這種狀態,客戶端在接收到fin後將會響應乙個rst,伺服器端接收到rst後會認為這是乙個錯誤。如果tcp協議能夠正常完成必要的操作而終止雙方的資料流傳輸,就必須完全正確的傳輸四次握手的四個節,不能有任何的丟失。這就是為什麼socket在關閉後,仍然處於 time_wait狀態,因為他要等待以便重發ack。

如果目前連線的通訊雙方都已經呼叫了close(),假定雙方都到達closed狀態,而沒有time_wait狀態時,就會出現如下的情況。現在有乙個新的連線被建立起來,使用的ip位址與埠與先前的完全相同,後建立的連線又稱作是原先連線的乙個化身。還假定原先的連線中有資料報殘存於網路之中,這樣新的連線收到的資料報中有可能是先前連線的資料報。為了防止這一點,tcp不允許從處於time_wait狀態的socket建立乙個連線。處於time_wait狀態的socket在等待兩倍的msl時間以後(之所以是兩倍的msl,是由於msl是乙個資料報在網路中單向發出到認定丟失的時間,乙個資料報有可能在傳送圖中或是其響應過程中成為殘餘資料報,確認乙個資料報及其響應的丟棄的需要兩倍的msl),將會轉變為closed狀態。這就意味著,乙個成功建立的連線,必然使得先前網路中殘餘的資料報都丟失了。

由於time_wait狀態所帶來的相關問題,我們可以通過設定so_linger標誌來避免socket進入time_wait狀態,這可以通過傳送rst而取代正常的tcp四次握手的終止方式。但這並不是乙個很好的主意,time_wait對於我們來說往往是有利的。

time_wait狀態對http影響

根據tcp協議,主動發起關閉的一方,會進入time_wait狀態,持續2*msl(max segment lifetime),預設為240秒。值得一說的是,對於基於tcp的http協議,關閉tcp連線的是server端,這樣,server端會進入time_wait狀態,可想而知,對於訪問量大的web server,會存在大量的time_wait狀態,假如server一秒鐘接收1000個請求,那麼就會積壓240*1000=240,000個time_wait的記錄,維護這些狀態給server帶來負擔。當然現代作業系統都會用快速的查詢演算法來管理這些time_wait,所以對於新的tcp連線請求,判斷是否hit中乙個time_wait不會太費時間,但是有這麼多狀態要維護總是不好。

http協議1.1版規定default行為是keep-alive,也就是會重用tcp連線傳輸多個request/response,乙個主要原因就是發現了這個問題。還有乙個方法減緩time_wait壓力就是把系統的2*msl時間減少,因為240秒的時間實在是忒長了點,對於windows,修改登錄檔,在hkey_local_machine/ system/currentcontrolset/services/ tcpip/parameters上新增乙個dword型別的值tcptimedwaitdelay,一般認為不要少於60,不然可能會有麻煩。

java 執行緒 執行緒的狀態及其狀態的轉換

new 新建立執行緒,初始態 runnable 可執行狀態,當前狀態的執行緒位於 可執行執行緒池 中,變得可執行,只等待獲取cpu的使用權,即當前執行緒獲得了除cpu以外的所有資源。running 正在執行。此時執行緒獲得了cpu的使用權,執行程式 blocked 阻塞狀態。執行緒因為某種原因放棄了...

Android 對電池狀態的監視

最近在開發乙個與gps相關的專案,因為其中涉及到了gps的使用,眾所周知,gps是相當耗電的,因此就想著怎麼能知道當前的電量,並且在電量達到乙個下限的時候,及時提醒給使用者,以根據情況關閉gps,節省電量,以備 急用,後來查資料,看api,終於找到了方法,怎麼來監視電量,根據電量的變化來獲取當前的電...

對TCP狀態轉換的理解

listen 這個也是非常容易理解的乙個狀態,表示伺服器端的某個socket處於監聽狀態,可以接受連線了。syn rcvd 這個狀態表示接收到了syn報文,在正常情況下,這個狀態是伺服器端的socket在建立tcp連線時的三次握手會話過程中的乙個中間狀態,很短暫,基本上用netstat你是很難看到這...