技术解析

TIME_WAIT 居高不下怎么办?
0
2021-07-02 16:42:03
idczone
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'显示 TIME_WAIT 太多了



/etc/sysctl.conf 如下

net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 0
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
net.ipv4.tcp_max_tw_buckets = 6000
net.ipv4.tcp_sack = 1
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_rmem = 4096 87380 4194304
net.ipv4.tcp_wmem = 4096 16384 4194304
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.netdev_max_backlog = 262144
net.core.somaxconn = 262144
net.ipv4.tcp_max_orphans = 3276800
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_mem = 94500000 915000000 927000000
net.ipv4.tcp_fin_timeout = 1
net.ipv4.tcp_keepalive_time = 30
net.ipv4.ip_local_port_range = 1024 65000


带宽还没跑满,该如何优化呢?
说说这服务器是干啥呀?咱不能二话不说就改底层系统配置啊。

跑 nginx 的。 cpu 、内存、带宽占用都正常。

这么点不算多吧。

TIME_WAIT 比 ESTABLISHED 高出不少

ESTABLISHED,SYN_REV 的数量都不多说明你的 nginx 服务器连接数量不多啊, TCP 的 TIME_WAIT 状态是通信双方主动关闭 sockfd 方会进入此状态,肯定不是 nginx 导致的,你要看是什么进程产生了 TIME_WAIT 。

查了下,是 nginx 默认使用短连接...

出现 TIME_WAIT 的原因是因为服务器主动关闭了 TCP 连接,无论作为 client 还是 server ,哪方主动 close TCP 连接,必然在这方出现 TIME_WAIT 。
所以要避免出现 TIME_WAIT ,就是不主动关闭 TCP 连接。
如果你的机器纯 nginx 反向代理,没有别的。那:
1 、 http 段的 keepalive 开启,不主动关闭浏览器客户端的连接。
2 、 upstream 段的 keepalive 开启,不主动关闭与后端 upstream 服务器的连接。同时需要修改 Proxy Header , HTTP/1.1 协议,移除掉 http close 头
如果你的机器还跑了 php ,那可能连接 mysql 是吧?
php 连接 mysql 的函数,使用 persistent 持久连接。
跑了 php ,可能连接 redis ?
php 连接 redis 的函数,使用 persistent 持久连接。
要看你的业务,系统底层怎么改都不能彻底解决 TIME_WAIT , TCP 协议设计如此。

只开了 80 端口,只运行了 nginx 。
没跑反代和 php ,只跑了 html 静态站。

根本不是问题,不用解决。
TIME_WAIT 本身也不会占用很多资源,何必要解决。
建议多看看 TCPIP 协议相关内容。

现在的问题是打开页面时快时慢,有一阵瞬间打开,有一阵得等好几秒才有响应(感觉像服务器处理不过来,在排队的样子)。 ping 值一直是稳定的,带宽和 cpu 内存也是波动不大。

那你应该看发送队列是不是满了。通过 ss -l 和 netstat 。这跟 TIME_WAIT 没关系。

upstream 中默认是长连接吗,还是每个请求来都会重新去连接后端的 php

默认短连接,每次都要三次握手。 upstream 里加了 keepalive ,并且配合 proxy/fastcgi 头的修改才是长连接。

总之这个配置不能乱改,有一次我参照晚上找的方法该了,貌似就是那个重用连接。
结果 TIME_WAIT 下来了,程序接入变得不稳定。
差点没把老板气急死。

数据地带为您的网站提供全球顶级IDC资源
在线咨询
专属客服