如何減少 TIME_WAIT 中的套接字數量?
Ubuntu 伺服器 10.04.1 x86
我在 Nginx 後面有一台帶有 FCGI HTTP 服務的機器,它為許多不同的客戶端提供許多小的 HTTP 請求。(高峰時段每秒約 230 個請求,帶標頭的平均響應大小為 650 字節,每天有數百萬個不同的客戶端。)
結果,我有很多套接字,掛在 TIME_WAIT 中(使用下面的 TCP 設置擷取圖表):
我想減少套接字的數量。
除了這個我還能做什麼?
$ cat /proc/sys/net/ipv4/tcp_fin_timeout 1 $ cat /proc/sys/net/ipv4/tcp_tw_recycle 1 $ cat /proc/sys/net/ipv4/tcp_tw_reuse 1
更新:機器上實際服務佈局的一些細節:
client -----TCP-socket--> nginx(負載均衡反向代理) -----TCP-socket--> nginx (worker) --domain-socket--> fcgi-軟體 --single-persistent-TCP-socket--> Redis --single-persistent-TCP-socket--> MySQL(其他機器)
我可能也應該切換負載平衡器 –> 工作程序連接到域套接字,但是關於 TIME_WAIT 套接字的問題仍然存在——我計劃很快在另一台機器上添加第二個工作程序。在這種情況下將無法使用域套接字。
您應該開始做的一件事是修復
net.ipv4.tcp_fin_timeout=1
. 那太低了,你可能不應該低於30。因為這是在 nginx 後面。這是否意味著 nginx 充當反向代理?如果是這種情況,那麼您的連接是 2 倍(一個到客戶端,一個到您的 Web 伺服器)。你知道這些插座屬於哪一端嗎?
更新:
fin_timeout 是他們在 FIN-WAIT-2 中停留的時間(來自
networking/ip-sysctl.txt
核心文件):tcp_fin_timeout - INTEGER Time to hold socket in state FIN-WAIT-2, if it was closed by our side. Peer can be broken and never close its side, or even died unexpectedly. Default value is 60sec. Usual value used in 2.2 was 180 seconds, you may restore it, but remember that if your machine is even underloaded WEB server, you risk to overflow memory with kilotons of dead sockets, FIN-WAIT-2 sockets are less dangerous than FIN-WAIT-1, because they eat maximum 1.5K of memory, but they tend to live longer. Cf. tcp_max_orphans.
我認為您可能只需要讓 Linux 將 TIME_WAIT 套接字數量與它們的 32k 上限保持一致,這就是 Linux 回收它們的地方。此連結中提到了此 32k :
此外,我發現 /proc/sys/net/ipv4/tcp_max_tw_buckets 令人困惑。儘管預設設置為 180000,但當我的系統上有 32K TIME_WAIT 套接字時,無論最大 tw 桶數如何,我都會看到 TCP 中斷。
此連結還表明 TIME_WAIT 狀態為 60 秒,無法通過 proc 進行調整。
隨機有趣的事實:
您可以使用 netstat 為每個套接字查看 timewait 上的計時器
netstat -on | grep TIME_WAIT | less
Reuse Vs Recycle:
這些有點意思,讀起來像重用啟用 time_Wait 套接字的重用,並且 recycle 將其置於 TURBO 模式:
tcp_tw_recycle - BOOLEAN Enable fast recycling TIME-WAIT sockets. Default value is 0. It should not be changed without advice/request of technical experts. tcp_tw_reuse - BOOLEAN Allow to reuse TIME-WAIT sockets for new connections when it is safe from protocol viewpoint. Default value is 0. It should not be changed without advice/request of technical experts.
我不建議使用 net.ipv4.tcp_tw_recycle 因為它會導致 NAT 客戶端出現問題。
也許您可以嘗試不同時打開這兩個,看看它有什麼效果(一次嘗試一個,看看它們是如何獨立工作的)?我會使用
netstat -n | grep TIME_WAIT | wc -l
比 Munin 更快的回饋。