生产Nginx现大量TIME-WAIT,连接耗尽,处理流程

2023-05-16  本文已影响0人  前浪浪奔浪流

TIME_WAIT的4种查询方式

1、netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
# netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
ESTABLISHED 660
FIN_WAIT1 3
CLOSING 2
SYN_SENT 1
TIME_WAIT 156

TIME_WAIT 156

2、ss -s
image.png
3、netstat -nat |awk '{print $6}'|sort|uniq -c|sort -rn
image.png
4、 统计 TIME_WAIT 连接的本地地址

netstat -an | grep TIME_WAIT | awk '{print $4}' | sort | uniq -c | sort -n -k1


image.png
5、尝试抓取 tcp 包
tcpdump tcp -i any -nn port 8080 | grep "172.11.11.11"
6、系统参数优化

需要修改内核参数,然后重启:

net.ipv4.tcp_tw_reuse = 1  #开启快速回收
net.ipv4.tcp_tw_recycle = 1   
#(在NAT网络中不建议开启,要设置为0),并且开启net.ipv4.tcp_timestamps = 1以上两个参数才生效。

语句如下:

echo "net.ipv4.tcp_tw_reuse = 1" >> /etc/sysctl.conf 
echo "net.ipv4.tcp_tw_recycle = 1" >> /etc/sysctl.conf
echo "net.ipv4.tcp_timestamps = 1" >> /etc/sysctl.conf
sysctl -p    #重新加载配置文件
7、nginx 配置优化

当使用nginx作为反向代理时,为了支持长连接,需要做到两点:
从client到nginx的连接是长连接;
从nginx到server的连接是长连接;
保持和client的长连接:

http {
    keepalive_timeout 120s 120s;
    keepalive_requests 1000;
}
keepalive_timeout设置
keepalive_timeout timeout [header_timeout];
keepalive_requests理解设置

keepalive_requests指令用于设置一个keep-alive连接上可以服务的请求的最大数量,当最大请求数量达到时,连接被关闭。默认是100。

这个参数的真实含义,是指一个keep alive建立之后,nginx就会为这个连接设置一个计数器,记录这个keep alive的长连接上已经接收并处理的客户端请求的数量。如果达到这个参数设置的最大值时,则nginx会强行关闭这个长连接,逼迫客户端不得不重新建立新的长连接。

保持和server的长连接

为了让nginx和后端server(nginx称为upstream)之间保持长连接,典型设置如下:(默认nginx访问后端都是用的短连接(HTTP1.0),一个请求来了,Nginx 新开一个端口和后端建立连接,后端执行完毕后主动关闭该链接)

location / {
    proxy_http_version 1.1;
    proxy_set_header Connection keep-alive;
    proxy_pass http://httpurl;
}

HTTP协议中对长连接的支持是从1.1版本之后才有的,因此最好通过proxy_http_version指令设置为”1.1”;
从client过来的http header,因为即使是client和nginx之间是短连接,nginx和upstream之间也是可以开启长连接的。

keepalive理解设置

此处keepalive的含义不是开启、关闭长连接的开关;也不是用来设置超时的timeout;更不是设置长连接池最大连接数。官方解释:

The connections parameter sets the maximum number of idle keepalive connections to upstream servers connections(设置到upstream服务器的空闲keepalive连接的最大数量)

When this number is exceeded, the least recently used connections are closed. (当这个数量被突破时,最近使用最少的连接将被关闭)

It should be particularly noted that the keepalive directive does not limit the total number of connections to upstream servers that an nginx worker process can open.(特别提醒:keepalive指令不会限制一个nginx worker进程到upstream服务器连接的总数量)

总结:

keepalive 这个参数一定要小心设置,尤其对于QPS比较高的场景,推荐先做一下估算,根据QPS和平均响应时间大体能计算出需要的长连接的数量。

比如前面10000 QPS和100毫秒响应时间就可以推算出需要的长连接数量大概是1000. 然后将keepalive设置为这个长连接数量的10%到30%。比较懒的同学,可以直接设置为keepalive=1000之类的,一般都OK的了。

综上,出现大量TIME_WAIT的情况

1)导致 nginx端出现大量TIME_WAIT的情况有两种:

keepalive_requests设置比较小,高并发下超过此值后nginx会强制关闭和客户端保持的keepalive长连接;(主动关闭连接后导致nginx出现TIME_WAIT)

keepalive设置的比较小(空闲数太小),导致高并发下nginx会频繁出现连接数震荡(超过该值会关闭连接),不停的关闭、开启和后端server保持的keepalive长连接;

2)导致后端server端出现大量TIME_WAIT的情况:

nginx没有打开和后端的长连接,即:没有设置proxy_http_version 1.1;和proxy_set_header Connection “”;从而导致后端server每次关闭连接,高并发下就会出现server端出现大量TIME_WAIT

上一篇下一篇

猜你喜欢

热点阅读