By fireworks2@foxmail.com
有关 TCP 下的各个状态转移,认真分析一遍就会对内在机理有个大致了解,这里着重说一下困扰大家最多的两种 WAIT 状态。
1. TIME_WAIT
TIME_WAIT 是主动关闭 TCP 连接的那一方出现的状态,系统会在 TIME_WAIT 状态下等待 2MSL(maximum segment lifetime )后才能释放连接(端口)。通常约合 4 分钟以内。
进入 TIME_WAIT 状态等待 2MSL 的目的:确保连接可靠地关闭,避免产生套接字混淆(同一个端口对应多个套接字)。
服务器产生大量 TIME_WAIT 的原因:服务器存在大量的主动关闭操作,需关注程序何时会执行主动关闭(如批量清理长期空闲的套接字等操作)。一般我们自己写的服务器进行主动断开连接的不多,除非做了空闲超时之类的管理。
2. CLOSE_WAIT
CLOSE_WAIT 是被动关闭 TCP 连接时产生的,如果收到另一端关闭连接的请求后,本地不关闭相应套接字就会导致本地套接字进入这一状态。如果存在大量的 CLOSE_WAIT,说明客户端并发量大,且服务器未能正常感知客户端的退出,也并未及时 close 这些套接字。
为了尽量避免在单台主机上出现大量这些状态的套接字,大致有以下几种做法:
a. TIME_WAIT——调整一下系统的参数,缩短套接字在这些状态下存活的时间
b. CLOSE_WAIT——设置套接字相关选项,打开KEEP_ALIVE,探测对端的存活情况 (如果不存活,就close;epoll 会返回 IN 事件)
c. 该 close 时就要 close(避免大量 CLOSE_WAIT),不要胡乱 close(避免大量 TIME_WAIT)
PS:
具体采用什么办法来解决问题,还得看具体情况。
=== =============== 和TCP相关的一些配置参数==================
linux
cd /proc/sys/net/ipv4/ 可以看到各个网络相关的参数
可以往 /etc/sysctl.conf 添加参数配置,如
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 10
...
然后执行 sysctl -p 使之生效