減少Linux伺服器TIME WAIT過多問題

2022-09-12 16:33:27 字數 3671 閱讀 5412

time_wait狀態的意義:

客戶端與伺服器端建立tcp/ip連線後關閉socket後,伺服器端連線的埠

狀態為time_wait

是不是所有執行主動關閉的socket都會進入time_wait狀態呢?

有沒有什麼情況使主動關閉的socket直接進入closed狀態呢?

主動關閉的一方在傳送最後乙個 ack 後

就會進入 time_wait 狀態 停留2msl(max segment lifetime)時間

這個是tcp/ip必不可少的,也就是「解決」不了的。

也就是tcp/ip設計者本來是這麼設計的

主要有兩個原因

1。防止上一次連線中的包,迷路後重新出現,影響新連線

(經過2msl,上一次連線中所有的重複包都會消失)

2。可靠的關閉tcp連線

在主動關閉方傳送的最後乙個 ack(fin) ,有可能丟失,這時被動方會重新發

fin, 如果這時主動方處於 closed 狀態 ,就會響應 rst 而不是 ack。所以

主動方要處於 time_wait 狀態,而不能是 closed 。

time_wait 並不會占用很大資源的,除非受到攻擊。

在squid伺服器中可輸入如下命令:

#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:伺服器在等待進入呼叫

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

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

established:正常資料傳輸狀態

fin_wait1:應用說它已經完成

fin_wait2:另一邊已同意釋放

itmed_wait:等待所有分組死掉

closing:兩邊同時嘗試關閉

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

last_ack:等待所有分組死掉

也就是說,這條命令可以把當前系統的網路連線狀態分類彙總。

下面解釋一下為啥要這樣寫:

乙個簡單的管道符連線了netstat和awk命令。

先來看看netstat:

netstat -n

active internet connections (w/o servers)

proto recv-q send-q local address foreign address state

tcp 0 0 123.123.123.123:80 234.234.234.234:12345 time_wait

你實際執行這條命令的時候,可能會得到成千上萬條類似上面的記錄,不過我們就拿其中的一條就足夠了。

再來看看awk:

/^tcp/

濾出tcp開頭的記錄,遮蔽udp, socket等無關記錄。

state

相當於定義了乙個名叫state的陣列

nf表示記錄的字段數,如上所示的記錄,nf等於6

$nf表示某個欄位的值,如上所示的記錄,$nf也就是$6,表示第6個字段的值,也就是time_wait

state[$nf]

表示陣列元素的值,如上所示的記錄,就是state[time_wait]狀態的連線數

++state[$nf]

表示把某個數加一,如上所示的記錄,就是把state[time_wait]狀態的連線數加一

end表示在最後階段要執行的命令

for(key in state)

遍歷陣列

print key,」\t」,state[key]

列印陣列的鍵和值,中間用\t製表符分割,美化一下。

如發現系統存在大量time_wait狀態的連線,通過調整核心引數解決,

vim /etc/sysctl.conf

編輯檔案,加入以下內容:

net.ipv4.tcp_syncookies = 1

net.ipv4.tcp_tw_reuse = 1

net.ipv4.tcp_tw_recycle = 1

net.ipv4.tcp_fin_timeout = 30

然後執行 /sbin/sysctl -p 讓引數生效。

linux下高併發的squid伺服器,tcp time_wait套接字數量經常達到兩、三萬,伺服器很容易被拖死。通過修改linux核心引數,可以減少squid伺服器的time_wait套接字數量。

vi /etc/sysctl.conf

增加以下幾行:引用

net.ipv4.tcp_fin_timeout = 30

net.ipv4.tcp_keepalive_time = 1200

net.ipv4.tcp_syncookies = 1

net.ipv4.tcp_tw_reuse = 1

net.ipv4.tcp_tw_recycle = 1

net.ipv4.ip_local_port_range = 1024 65000

net.ipv4.tcp_max_syn_backlog = 8192

net.ipv4.tcp_max_tw_buckets = 5000

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

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

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

net.ipv4.tcp_fin_timeout = 30 表示如果套接字由本端要求關閉,這個引數決定了它保持在fin-wait-2狀態的時間。

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套接字拖死。

執行以下命令使配置生效:

/sbin/sysctl -p

減少Linux伺服器TIME WAIT過多問題

time wait狀態的意義 客戶端與伺服器端建立tcp ip連線後關閉socket後,伺服器端連線的埠 狀態為time wait 是不是所有執行主動關閉的socket都會進入time wait狀態呢?有沒有什麼情況使主動關閉的socket直接進入closed狀態呢?主動關閉的一方在傳送最後乙個 a...

減少linux伺服器大量TIME WAIT

將專案部署到linux上後,發現系統有大量的time wait狀態的鏈結,大量time wait狀態的鏈結不能被及時 導致的結果就是系統可用socket被耗盡而無法處理新的請求。對於http協議的短連線請求,應該要防止產生大量的time wait,我們可以通過設定linux網路引數來達到目的,步驟如...

如何減少Linux伺服器TIME WAIT過多

time wait狀態的意義 客戶端與伺服器端建立tcp ip連線後關閉socket後,伺服器端連線的埠狀態為time wait 是不是所有執行主動關閉的socket都會進入time wait狀態呢?有沒有什麼情況使主動關閉的socket直接進入closed狀態呢?主動關閉的一方在傳送最後乙個 ac...