Ubuntu

如何減少 TIME_WAIT 中的套接字數量?

  • September 9, 2014

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 更快的回饋。

引用自:https://serverfault.com/questions/212093