TCP 情况下,TIME_WAIT 和 CLOSE_WAIT 状态
2011-04-12 21:56
549 查看
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:
通过 keepalive 可以强制从 close_wait 解救出来套接字,不过如果不进行 close 的话,对应的套接字其实尚未关闭,但此时原来占据的端口已经可用了。在 keepalive 探测到对端已经断开或关闭后,产生的事件为可读,recv返回0个字节。此时即使不 close 掉套接字描述符,端口仍将被释放。因与系统具体实现相关,为了便于移植,还是尽量不用为妙,或者自行在应用层实现一个更通用的心跳功能
。
具体采用什么办法来解决问题,还得看具体情况。
===
=============== 和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 使之生效
有关 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:
通过 keepalive 可以强制从 close_wait 解救出来套接字,不过如果不进行 close 的话,对应的套接字其实尚未关闭,但此时原来占据的端口已经可用了。在 keepalive 探测到对端已经断开或关闭后,产生的事件为可读,recv返回0个字节。此时即使不 close 掉套接字描述符,端口仍将被释放。因与系统具体实现相关,为了便于移植,还是尽量不用为妙,或者自行在应用层实现一个更通用的心跳功能
。
具体采用什么办法来解决问题,还得看具体情况。
===
=============== 和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 使之生效
相关文章推荐
- TCP连接状态分析:SYNC_RECV,CLOSE_WAIT,TIME_WAIT
- 简析TCP协议的TIME_WAIT与CLOSE_WAIT状态
- TCP的状态,兼谈Close_Wait和Time_Wait的状态 (keepalive机制)
- TCP连接状态:CLOSE_WAIT和TIME_WAIT
- 关闭socket链接过程中的TCP状态:TIME_WAIT状态(开启地址重用),CLOSE_WAIT状态
- TCP连接状态分析:SYNC_RECV,CLOSE_WAIT,TIME_WAIT
- TCP的状态兼谈Close_Wait和Time_Wait的状态
- TCP连接状态分析:SYNC_RECV,CLOSE_WAIT,TIME_WAIT
- TCP的TIME_WAIT与CLOSE_WAITE状态
- TCP的状态兼谈Close_Wait和Time_Wait的状态
- TCP的状态兼谈Close_Wait和Time_Wait的状态
- TCP之 TIME_WAIT和CLOSE_WAIT 状态 的原因分析和处理
- TCP的time_wait、close_wait状态
- 通讯系统经验谈【一】TCP连接状态分析:SYNC_RECV,CLOSE_WAIT,TIME_WAIT
- TCP连接TIME_WAIT和CLOSE_WAIT状态
- TCP的CLOSE_WAIT和TIME_WAIT状态
- TCP 协议状态分解---服务器TIME_WAIT和CLOSE_WAIT详解和解决办法
- 通讯系统经验谈【一】TCP连接状态分析:SYNC_RECV,CLOSE_WAIT,TIME_WAIT
- TCP的状态兼谈Close_Wait和Time_Wait的状态
- 通讯系统经验谈TCP连接状态分析:SYNC_RECV,CLOSE_WAIT,TIME_WAIT