一、当大量的连接处于 time_wait 时,新建立 TCP 连接会出错,address already in use : connect 异常。
TCP 本地端口数量,上限为 65535(6.5w),这是因为 TCP 头部使用 16 bit,存储「端口号」,因此约束上限为 65535。
二、TCP 连接中,「主动发起关闭连接」的一端,会进入 time_wait 状态;
time_wait 状态,默认会持续 2 MSL(报文的最大生存时间)
time_wait 状态下,TCP 连接占用的端口,无法被再次使用
net.ipv4.ip_local_port_range = 1024 65000 #端口数和这个参数有关系
三、大量 time_wait 状态存在,会导致新建 TCP 连接会出错,导致服务器资源使用上升;出现address already in use : connect 异常
四、解决方法:服务器端允许 time_wait 状态的 socket 被重用;缩减 time_wait 时间,设置为 1 MSL(即,2 mins)
操作系统层面主要修改配置文件/etc/sysctl.conf
1、允许将TIME_WAIT状态的socket重新用于新的TCP连接:net.ipv4.tcp_tw_reuse = 1 #默认为0,表示关闭,如果为0,修改为1
2、快速回收TIME_WAIT状态的socket net.ipv4.tcp_tw_recycle = 1 #修改为1,默认为0
3、修改time_wait连接数的回收时间:cat /proc/sys/net/ipv4/tcp_fin_timeout #查看默认的MSL值
net.ipv4.tcp_fin_timeout = 30 #如果为60,修改为30s回收
4、sudo sysctl -p 使配置生效即可
备注:TCP连接数统计脚本:统计出当前分配连接数的进程,通过进程可以找到对应的服务,如果是服务关闭连接的姿势不对,业务方优化即可
#!/bin/sh
for i in /proc/* ;
do
if [ -d $i/fd ];then
echo $i $(ls $i/fd -l | grep socket: |wc -l)
fi
done