登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

SeaRiver Blog

实力才是你一生最好的依靠!

 
 
 

日志

 
 

Socket TIME_WAIT 问题   

2008-09-09 09:47:20|  分类: network |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
TIME_WAIT状态

根据TCP协议定义的4次握手断开连接规定,发起socket主动关闭的一方socket将进入TIME_WAIT状态,TIME_WAIT状态将持续2个MSL(Max Segment Lifetime),在Windows下默认为4分钟,即240秒,TIME_WAIT状态下的socket不能被回收使用. 具体现象是对于一个处理大量短连接的服务器,如果是由服务器主动关闭客户端的连接,将导致服务器端存在大量的处于TIME_WAIT状态的socket,甚至比处于Established状态下的socket多的多,严重影响服务器的处理能力,甚至耗尽可用的socket,停止服务. TIME_WAIT是TCP协议用以保证被重新分配的socket不会受到之前残留的延迟重发报文影响的机制,是必要的逻辑保证.
可以用如下代码尝试关闭TIME_WAIT,但这样作是很危险的,违背TCP协议的,也不一定有效果.
linger InternalLinger = { 1, 0 };
::setsockopt(socket, SOL_SOCKET, SO_LINGER, (const char*)&InternalLinger, sizeof(linger));

中庸的做法是,可在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters,添加名为TcpTimedWaitDelay的
DWORD键,设置为30-240,以缩短TIME_WAIT的等待时间,这也是对IIS服务器的优化手段之一.编程上,除非必要,应尽量让客户端发起断开操作.

 

Socket TIME_WAIT 问题  - SeaRiver - SeaRiver  Blog

评论

# re: 讨厌的 Socket TIME_WAIT 问题

在设置中强制修改TIME_WAIT的时间对于延迟比较严重的末端节点非常有害,最好在设计中保证由客户端开始,由客户端结束。当然如果需要服务器发起大规模并发,可以考虑在中层建立session server。这种方法实践证明非常可靠,并且实现简单。 

TCP结束的过程如下:

Server                             Client

-------------- FIN -------------->  server: fin_wait_1

<------------- ACK --------------- client: close_wait  server:fin_wait_2

<------------- FIN  -------------- client发出fin之后就关闭

-------------- ACK ------------->  server发出ack后进入time_wait状态

Time_Wait的默认时间是2倍的MLS,就是240秒钟。MLS是TCP 片在网上的最长存活时间。
TIME_Wait的主要作用是保证关闭的TCP端口不立即被使用。因为当网络存在延迟时,可能当某个端口被关闭后,网络中还有一些重传的TCP片在发向这个端口,如果这个端口立即建立新的TCP连接,则可能会有影响。所以使用2倍的MSL时间来限制这个端口立即被使用。

现在的问题在于,4分钟的时间有点长。
因此,Time_wait的影响,我想,首先每个TCP连接都各自有个数据结构,叫TCP Control Block.Time_wait的时候这个数据结构没有被释放。所以当有太多的TCP连接时,内存可能会被占用很多。

对应方法:

修改Linux内核参数,减少TCP连接中的TIME_WAIT sockets

  新增的一组Apache服务器上线以来,我用netstat -an命令发现服务器中有大量状态为TIME-WAIT的TCP连接,于是用/sbin/sysctl -a查看了一下Linux的各项内核参数,并翻阅有关资料,决定修改其中的两项参数,以达到减少TCP连接中TIME-WAIT sockets的目的。
复制内容到剪贴板
代码:
vi /etc/sysctl.conf
编辑/etc/sysctl.conf文件,增加三行:
代码:
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
说明:
  net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;
  net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;
  net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。

  再执行以下命令,让修改结果立即生效:
代码:
/sbin/sysctl -p
用以下语句看了一下服务器的TCP状态:
复制内容到剪贴板
代码:
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
返回结果如下:
代码:
ESTABLISHED 1423
FIN_WAIT1 1
FIN_WAIT2 262
SYN_SENT 1
TIME_WAIT 962
效果:处于TIME_WAIT状态的sockets从原来的10000多减少到1000左右。处于SYN_RECV等待处理状态的sockets为0,原来的为50~300。
 
  评论这张
 
阅读(2126)| 评论(0)

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018