優化Linux下的內核TCP參數以提高系統性能 (TIME_WAIT處理)

摘要:優化Linux下的內核TCP參數以提高系統性能 內核的優化跟服務器的優化一樣,應本着穩定安全的原則。下面以Squid服務器爲例來說明,待客戶端與服務器端建立TCP/IP連接後就會關閉Socket,服務器端連接的端口狀態也就變爲TIME_WAIT了。

優化Linux下的內核TCP參數以提高系統性能


 內核的優化跟服務器的優化一樣,應本着穩定安全的原則。下面以Squid服務器爲例來說明,待客戶端與服務器端建立TCP/IP連接後就會關閉Socket,服務器端連接的端口狀態也就變爲TIME_WAIT了。那是不是所有執行主動關閉的Socket都會進入TIME_WAIT狀態呢?有沒有什麼情況可使主動關閉的Socket直接進入CLOSED狀態呢?答案是主動關閉的一方在發送最後一個ACK後就會進入TIME_WAIT狀態,並停留2MSL(報文最大生存)時間,這是TCP/IP必不可少的,也就是說這一點是“解決”不了的。

TCP/IP設計者如此設計,主要原因有兩個:

防止上一次連接中的包迷路後重新出現,影響新的連接(經過2MSL時間後,上一次連接中所有重複的包都會消失)。

爲了可靠地關閉TCP連接。主動關閉方發送的最後一個ACK(FIN)有可能會丟失,如果丟失,被動方會重新發送FIN,這時如果主動方處於 CLOSED狀態,就會響應 RST而不是ACK。所以主動方要處於TIME_WAIT狀態,而不能是CLOSED狀態。另外,TIME_WAIT 並不會佔用很大的資源,除非受到攻擊。

在Squid服務器中可輸入如下命令查看當前連接統計數:

netstat -n | awk'/^tcp/ {++S[$NF]} END{for(a in S) print a, S[a]}'

命令顯示結果如下所示:

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:等待所有分組死掉。

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

在Linux下高併發的Squid服務器中,TCP TIME_WAIT套接字的數量經常可達到兩三萬,服務器很容易就會被拖死。不過,可以通過修改Linux內核參數來減少Squid服務器的TIME_WAIT套接字數量,命令如下:

vim/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= 10000 65000

net.ipv4.tcp_max_syn_backlog= 8192

net.ipv4.tcp_max_tw_buckets= 5000

以下將簡單說明上面各個參數的含義:

net.ipv4.tcp_syncookies=1表示開啓SYN Cookies。當出現SYN等待隊列溢出時,啓用Cookie來處理,可防範少量的SYN攻擊。該參數默認爲0,表示關閉。

net.ipv4.tcp_tw_reuse=1表示開啓重用,即允許將TIME-WAIT套接字重新用於新的TCP連接。該參數默認爲0,表示關閉。

net.ipv4.tcp_tw_recycle=1表示開啓TCP連接中TIME-WAIT套接字的快速回收,該參數默認爲0,表示關閉。

net.ipv4.tcp_fin_timeout=30表示如果套接字由本端要求關閉,那麼這個參數將決定它保持在FIN-WAIT-2狀態的時間。

net.ipv4.tcp_keepalive_time=1200表示當Keepalived啓用時,TCP發送Keepalived消息的頻度改爲20分鐘,默認值是2小時。

net.ipv4.ip_local_port_range=10 000 65 000表示CentOS系統向外連接的端口範圍。其默認值很小,這裏改爲10 000到65 000。建議不要將這裏的最低值設得太低,否則可能會佔用正常的端口。

net.ipv4.tcp_max_syn_backlog=8192表示SYN隊列的長度,默認值爲1024,此處加大隊列長度爲8192,可以容納更多等待連接的網絡連接數。

net.ipv4.tcp_max_tw_buckets=5000表示系統同時保持TIME_WAIT套接字的最大數量,如果超過這個數字,TIME_WAIT套接字將立刻被清除並打印警告信息,默認值爲180 000,此處改爲5000。對於Apache、Nginx等服務器,前面介紹的幾個參數已經可以很好地減少TIME_WAIT套接字的數量,但是對於Squid來說,效果卻不大,有了此參數就可以控制TIME_WAIT套接字的最大數量,避免Squid服務器被大量的TIME_WAIT套接字拖死。

執行以下命令使內核配置立馬生效:

/sbin/sysctl –p

如果是用於Apache或Nginx等Web服務器,則只需要更改以下幾項即可:

net.ipv4.tcp_syncookies=1

net.ipv4.tcp_tw_reuse=1

net.ipv4.tcp_tw_recycle= 1

net.ipv4.ip_local_port_range= 10000 65000

執行以下命令使內核配置立馬生效:

/sbin/sysctl –p

如果是Postfix郵件服務器,則建議內核優化方案如下:

net.ipv4.tcp_fin_timeout= 30

net.ipv4.tcp_keepalive_time= 300

net.ipv4.tcp_tw_reuse= 1

net.ipv4.tcp_tw_recycle= 1

net.ipv4.ip_local_port_range= 10000 65000

kernel.shmmax =134217728

執行以下命令使內核配置立馬生效:

/sbin/sysctl –p

當然這些都只是最基本的更改,大家還可以根據自己的需求來更改內核的設置,比如我們的線上機器在高併發的情況下,經常會出現“TCP: too many orpharned sockets”的報錯儘量也要本着服務器穩定的最高原則。如果服務器不穩定的話,一切工作和努力就都會白費。如果以上優化仍無法滿足工作要求,則有可能需要定製你的服務器內核或升級服務器硬件。

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