CentOS7 TIME_WAIT过多调优
Write by lyc at 2020-12-1
参考博文:服务端 TCP 连接的 TIME_WAIT 问题分析与解决
1.大量的 TIME_WAIT 状态 TCP 连接,对业务上有什么影响?
Nginx 作为反向代理时,大量的短链接,可能导致 Nginx 上的 TCP 连接处于 TIME_WAIT
状态:
- 每一个
TIME_WAIT
状态,都会占用一个「本地端口」。TCP 本地端口数量,上限为65535
(6.5w),这是因为 TCP 头部使用 16 bit,存储「端口号」,因此约束上限为65535
- 当大量的连接处于
TIME_WAIT
时,新建立 TCP 连接会出错,address already in use : connect
异常 - TCP 连接中,「主动发起关闭连接」的一端,会进入
TIME_WAIT
状态 TIME_WAIT
状态,默认会持续 2 MSL(报文的最大生存时间),一般是 2x2 minsTIME_WAIT
状态下,TCP 连接占用的端口,无法被再次使用
2.TCP 连接的状态
统计 TCP 连接的状态
1 | $ netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' |
连接状态说明
1 | CLOSED # 无连接是活动的或正在进行 |
3.问题分析
大量的 TIME_WAIT 状态 TCP 连接存在,其本质原因是什么?
- 大量的短连接存在
- 特别是 HTTP 请求中,如果
connection
头部取值被设置为close
时,基本都由「服务端」发起主动关闭连接- 所以
TIME_WAIT
过多一般多存在于服务器端,比如 Nginx反向代理服务器,我们可以将Nginx服务器与Web服务器拆分来减少 TIME_WAIT
- 所以
- TCP 四次挥手关闭连接机制中,为了保证 ACK 重发和丢弃延迟数据,设置
TIME_WAIT
为 2 倍的MSL
(报文最大存活时间)
TIME_WAIT 状态:
- TCP 连接中,主动关闭连接的一方出现的状态;(收到 FIN 命令,进入 TIME_WAIT 状态,并返回 ACK 命令)
- 保持 2 个
MSL
时间,即,4 分钟;(MSL 为 2 分钟)
4.解决办法
对于客户端
作为客户端因为有端口65535问题,TIME_OUT 过多直接影响处理能力,打开
tw_reuse
即可解决,不建议同时打开tw_recycle
,帮助不大;tw_reuse
帮助客户端1s完成连接回收,基本可实现单机6w/s短连接请求,需要再高就增加IP数量;如果内网压测场景,且客户端不需要接收连接,同时
tw_recycle
会有一点点好处;业务上也可以设计由服务端主动关闭连接。
对于服务端(我们主要关注服务器端)
打开
tw_reuse
无效线上环境
tw_recycle
不建议打开- 服务器处于NAT 负载后,或者客户端处于NAT后(基本公司家庭网络基本都走NAT);
- 公网服务打开就可能造成部分连接失败,内网的话到时可以视情况打开;
- 像我所在公司对外服务都放在负载后面,负载会把 timestamp 都给清空,就算你打开也不起作用。
服务器 TIME_WAIT 高怎么办?
- 不像客户端有端口限制,处理大量 TIME_WAIT Linux已经优化很好了,每个处于 TIME_WAIT 状态下连接内存消耗很少
- 而且也能通过
tcp_max_tw_buckets
配置最大上限,现代机器一般也不缺这点内存。
业务上也可以设计由客户端主动关闭连接,首先发起关闭的一方会进入TIME-WAIT状态,另一方可以快速回收连接。
4.1 向外连接的端口范围(可以配置)
/proc/sys/net/ipv4/ip_local_port_range
- 表示用于向外连接的端口范围。
- 缺省情况下很小:32768到61000,改为10240到65000
1 | # 检查向外连接的端口范围 |
4.2 TIME_WAIT 快速回收(线上环境不建议使用)
/proc/sys/net/ipv4/tcp_timestamps
查看内核的时间戳支持,默认为1。如果是0,则修改为1。/proc/sys/net/ipv4/tcp_tw_recycle
开启TCP连接中 TIME_WAIT sockets 的快速回收,默认为0,表示关闭。==在NAT(Network Address Translation)网络下,会导致大量的TCP连接建立错误。如果没有技术大神的指点的话,千万不要去改动他。==/proc/sys/net/ipv4/tcp_tw_reuse
开启重用。允许将 TIME_WAIT sockets 重新用于新的TCP连接,默认为0,表示关闭。从协议设计上来看,对于TIME-WAIT状态的sockets重用到新的TCP连接上来说,是安全的。(用于客户端时的配置)
tcp_tw_recycle 这个开关,需要 net.ipv4.tcp_timestamps(默认开启的)这个开关开启才有效果。
1 | # 查看 TIME_WAIT 快速回收 |
4.3 控制 TIME_WAIT 套接字的最大数量(可以配置)
/proc/sys/net/ipv4/tcp_max_tw_buckets
- 表示系统同时保持 TIME_WAIT 套接字的最大数量
- 如果超过这个数字,TIME_WAIT 套接字将立刻被清除并打印警告信息。
- 系统日志中overflow 错误一直再刷屏
TCP: time wait bucket table overflow
- 默认为180000,改为 10000,16384,32786 都可以,根据当前服务器的内存值进行调整。
1 | # 查看 |
4.4 其他 TIME_WAIT 相关参数说明(保持默认,不要调整)
1 | /proc/sys/net/ipv4/tcp_syncookies # 1表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭; |