一、當大量的連接處于 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