解決TIME WAIT過多造成的問題

2022-07-10 09:48:08 字數 2719 閱讀 1568

tcp/ip time_wait狀態原理:

通訊雙方建立tcp連線後,主動關閉連線的一方就會進入time_wait狀態

客戶端主動關閉連線時,會傳送最後乙個ack後,然後會進入time_wait狀態,再停留2個msl時間(後有msl的解釋),進入closed狀態

下圖是以客戶端主動關閉連線為例,說明這一過程的:

為什麼time_wait狀態還需要等2msl後才能返回到closed狀態?

這是因為:雖然雙方都同意關閉連線了,而且握手的4個報文也都協調和傳送完畢,按理可以直接回到closed狀態(就好比從syn_send狀態到 establish狀態那樣);但是因為我們必須要假想網路是不可靠的,你無法保證你最後傳送的ack報文會一定 被對方收到,因此對方處於 last_ack狀態下的socket可能會因為超時未收到ack報文,而重發fin報文,所以這個time_wait狀態的作用就是用來重發可能丟失的 ack報文,並保證於此。

closed:無連線是活動的或正在進行

listen:伺服器在等待進入呼叫

syn_recv:乙個連線請求已經到達,等待確認

syn_sent:應用已經開始,開啟乙個連線

established:正常資料傳輸狀態

fin_wait1:應用說它已經完成

fin_wait2:另一邊已同意釋放

itmed_wait:等待所有分組死掉

closing:兩邊同時嘗試關閉

time_wait:另一邊已初始化乙個釋放

last_ack:等待所有分組死掉

常用的三個狀態是:established 表示正在通訊,time_wait 表示主動關閉,close_wait 表示被動關閉。

伺服器出現異常都是下需的兩種狀態:

1.伺服器保持了大量time_wait狀態

2.伺服器保持了大量close_wait狀態

因為linux分配給乙個使用者的檔案控制代碼是有限的,而time_wait和close_wait兩種狀態如果一直被保持,那麼意味著對應數目的通道就一直被佔著,並只是佔不用,一旦達到控制代碼數上限,新的請求就無法被處理了,接著就是大量too many open files異常,tomcat崩潰!

優化系統核心參 數解決time_wait可能很容易,但是應對close_wait的情況還是需要從程式本身出發。現在來分別說說這兩種情況的處理方法:

爬蟲伺服器或者web伺服器如果沒有做核心引數優化,就會出現大量的time_wait狀態。time_wait是主動關閉連線的一方保持的狀態,對於爬蟲伺服器來說他本身就是「客戶端」,在完成乙個爬取任務之後,他就 會發起主動關閉連線,從而進入time_wait的狀態,然後在保持這個狀態2msl(max segment lifetime)時間之後,徹底關閉**資源。

編輯核心檔案/etc/sysctl.conf

#  vim /etc/sysctl.conf

# 將一下**輸入進去

net.ipv4.tcp_syncookies = 1          #表示開啟syn cookies。當出現syn等待佇列溢位時,啟用cookies來處理,可防範少量syn攻擊,預設為0,表示關閉。                      

net.ipv4.tcp_tw_recycle = 1           #表示開啟tcp連線中time-wait sockets的快速**,預設為0,表示關閉

。net.ipv4.tcp_tw_reuse = 1             #表示開啟重用。允許將time-wait sockets重新用於新的tcp連線,預設為0,表示關閉。            

net.ipv4.tcp_fin_timeout = 30        #修改系預設的 timeout 時間

使引數生效:

#   sysctl -p

/etc/sysctl.conf是乙個允許改變正在執行中的linux系統的介面,它包含一些tcp/ip堆疊和虛擬記憶體系統的高階選項,修改核心引數永久生效 

簡單來說,就是開啟系統的timewait重用和快速**

如果以上配置調優後效能還不理想,可繼續修改一下配置:

net.ipv4.tcp_keepalive_time = 1200

#表示當keepalive起用的時候,tcp傳送keepalive訊息的頻度。預設是2小時,改為20分鐘。

net.ipv4.ip_local_port_range = 1024 65000

#表示用於向外連線的埠範圍。預設情況下很小:32768到61000,改為1024到65000。

net.ipv4.tcp_max_syn_backlog = 8192

#表示syn佇列的長度,預設為1024,加大佇列長度為8192,可以容納更多等待連線的網路連線數。

net.ipv4.tcp_max_tw_buckets = 5000

#表示系統同時保持time_wait套接字的最大數量,如果超過這個數字,time_wait套接字將立刻被清除並列印警告資訊。

預設為180000,改為5000。對於apache、nginx等伺服器,上幾行的引數可以很好地減少time_wait套接字數量,但是對於 squid,效果卻不大。此項引數可以控制time_wait套接字的最大數量,避免squid伺服器被大量的time_wait套接字拖死

請參考:

TIME WAIT過多及解決

最近用http load做壓測,跑出來一大串 cannot assign requested address 的錯誤,查了一下,是time wait過多導致的。因為短時間內有太多連線,所以占用了大量埠,同時關閉連線後又處於time wait狀態,埠不能復用,所以慢慢的無埠可用,所以就 cannot ...

解決TIME WAIT過多問題

netstat n awk tcp end last ack 14 syn recv 348 established 70 fin wait1 229 fin wait2 30 closing 33 time wait 18122 狀態 描述 closed 無連線是活動的或正在進行 listen 伺...

解決TIME WAIT過多問題

netstat n awk tcp end last ack 14 syn recv 348 established 70 fin wait1 229 fin wait2 30 closing 33 time wait 18122 狀態 描述 closed 無連線是活動的或正在進行 listen 伺...