CLOSED_WAIT & TIME_WAIT

最近維護的業務量與日俱增,服務器不斷出現各種問題。今天遇到了在開啓 MySQL pconnect 情況下 TCP CLOSE_WAIT 連接狀態激增的情況。CLOSE_WAIT 高達 8000 左右。

先來看看 TCP 協議是如何關閉一個連接的:

STEP 1: Client –FIN–> Server

STEP 2: Client <--ACK-- Server
此時 Client 處於FIN_WAIT_2 狀態;而 Server 處於 CLOSE_WAIT 狀態。

STEP 3: Client <--FIN-- Server
此時 Server 發送 FIN 給 Client,Server 置爲 LAST_ACK 狀態。

STEP 4: Client --ACK--> Server
Client 迴應 ACK ,此時 Server 真正置爲 CLOSED 狀態。

Server 處於 CLOSE_WAIT 狀態,而不是 LAST_ACK 狀態,說明還沒有發 FIN 給 Client,那麼可能是在關閉連接之前還有許多數據要發送或者其他事要做,導致沒有發這個 FIN packet。

默認情況下,一個 CLOSE_WAIT 會維持至少 2 個小時 (7200s) 的時間。通過修改一下 TCP 參數,來縮短這個時間:修改tcp_keepalive_* 系列參數有助於解決這個問題。

減少 CLOSE_WAIT:

net.ipv4.tcp_fin_timeout = 10
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_probes = 2
net.ipv4.tcp_keepalive_intvl = 2

減少 TIME_WAIT:

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.route.gc_timeout = 100
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_synack_retries = 1

說明:

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

net.ipv4.route.gc_timeout = 100
路由緩存刷新頻率, 當一個路由失敗後多長時間跳到另一個默認是300

net.ipv4.tcp_syn_retries = 1
對於一個新建連接,內核要發送多少個 SYN 連接請求才決定放棄。不應該大於255,默認值是5,對應於180秒左右。

連接狀態統計:

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






source:http://www.inanu.net/post/328.html


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