Nginx做前端Proxy時TIME_WAIT過多的問題


我們的DSP系統目前基本非凌晨時段的QPS都在10W以上,我們使用Golang來處理這些HTTP請求,Web服務器的前端用Nginx來做負載均衡,通過Nginx的proxy_pass來與Golang交互。

由於nginx代理使用了短鏈接的方式和后端交互的原因,使得系統TIME_WAIT的tcp連接很多:

shell> netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}'
TIME_WAIT 250263
CLOSE_WAIT 57
FIN_WAIT2 3
ESTABLISHED 2463
SYN_RECV 8

ss 比 netstat 要快,所以也可以用下面的命令來查看:

shell> ss -ant | awk 'NR>1 {++s[$1]} END {for(k in s) print k,s[k]}'

這會占用系統過多的端口,還浪費了系統資源,所以我們必須想辦法減少TIME_WAIT。

TIME_WAIT導致占用過多端口的一個影響是會占用我們需要使用到的端口,例如我們有個服務監聽的端口為8012,重啟的時候經常會提示端口被占用。
通過查看/proc/sys/net/ipv4/ip_local_port_range可以知道設置的Linux內核自動分配端口的端口范圍:

shell> cat /proc/sys/net/ipv4/ip_local_port_range
1025 65535

對於這個設置系統就會從1025~65535這個范圍內隨機分配端口來用於連接,而我們服務的8012端口剛好在這個范圍之內,所以如果8012剛好被系統分配出去使用了,則啟動我們服務的時候,就會提示端口被占用。

所以我們需要設置/proc/sys/net/ipv4/ip_local_reserved_ports來告訴系統給我們預留哪些端口,不可以用於自動分配。

shell> vim /etc/sysctl.conf
net.ipv4.ip_local_reserved_ports = 8012,11211-11220

shell> sysctl -p

關於預留端口的更具體信息可以參考:

上面我們解決了端口占用問題,但是我們還是需要解決TIME_WAIT過多的問題。
Nginx 1.1以上版本的upstream已經支持keep-alive的,所以我們可以開啟Nginx proxy的keep-alive來減少tcp連接:

upstream http_backend {
    server 127.0.0.1:8080;

    keepalive 16;
}

server {
    ...

    location /http/ {
        proxy_pass http://http_backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        ...
    }
}

可以參加Nginx的官方文檔: http://nginx.org/cn/docs/http/ngx_http_upstream_module.html#keepalive

開了keep-alive之后,TIME_WAIT明顯減少:

shell> netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}'
TIME_WAIT 12612
CLOSE_WAIT 11
FIN_WAIT1 4
FIN_WAIT2 1
ESTABLISHED 7667
SYN_RECV 3

另外不少文章提到可以修改系統的/etc/sysctl.conf配置來減少TIME_WAIT的tcp連接:

net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1

參見: http://blog.s135.com/post/271/

不過開啟tcp_tw_recycle可能會帶來一些不穩定的網絡問題,請參考:

關於sysctl相關配置的說明,請參考:
https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt

 

參考文章:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM