近来网站随着访问量的增加,服务器的压力也随之上升,一个很明显的状况便是服务端产生了大量的TIME_WAIT状态,它究竟是什么、对系统有何影响、为什么很多人对它如此敏感?
Google一下TIME_WAIT会有成千上万的文章,但总是别人的,今天自己整理一下对TIME_WAIT的认识。
TCP连接的终止
TCP建立一个连接至少需要交换三个分组,也因此称之为TCP的三路握手(three-way handshake),然而在TCP终止连接时,由于双方都需要发送一个FIN分节给对端确认,因此TCP终止连接一般是需要交换四个分节。具体来看:
1、 应用进程(active close)首先调用close,于是导致TCP发送一个FIN分节,表示数据已分送完毕,请求关闭套接字。
2、 另一端应用进程(passive close)接受收到FIN,并由该端的TCP确认(确认的过程是TCP发送ACK分节给对端套接字)。FIN的接受也作为文件结束符传递给上层应用进程。这里的文件结束符并非应用进程的EOF,在TCP字节流中,EOF的读或写通过收发一个特殊的FIN分节来实现。
3、 另端(passive close)应用进程在接受到文件束符后,会调用close关闭它的套接字,这导致该端的TCP也发送了一个FIN分节。
4、 主动关闭端(active close)接受到这个FIN后,TCP对它进行确认。(TCP发送ACK分节,值得注意的是主动关闭端在未接受到FIN之前,它的状态就是TIME_WAIT)。
这张图在google image中,花了五六分钟才找到,觉得这张图是最直观、易懂的。
TIME_OUT状态的存在的意义
从图中,很清晰的看到TIME_WAIT状态发生在了active close 端,产生的时间点是发送ACK K+1 分节之后,原因是防止ACK分节在网络中丢失(lost),此时passive close进入LAST_ACK状态,意为等待ACK分节,如果此时ACK分节真的丢失了(passive close端的LAST_ACK超时),那么passive close端将会再次发送一个FIN K分节给对端。这就是为什么在图中,出现两次FIN的分节。
这里有RFC的原文:
Once the final ACK has been sent on an active close, the port/connection cannot be relaeased and re-used for the time period 2MSL. This is twice the maximum segment life and this constraint is imposed in case the the final ACK is lost.
If the final ACK is lost then the passive closing host will time out awaiting an ACK in response to the closing FIN and will resend the FIN. If this arrives before the 2MSL time has expired there is no problem, after this time the FIN does not appear to belong to whatever connection might exist between the two clients.
TIME_OUT存在的理由用术语来描述,摘自UNIX Network Programming Vol1 中:
1、 可靠地实现TCP全双工连接的终止。
2、 允许老的重复分节在网络中消逝。
TIME_OUT状态的持续时间
图中标明了TIME_OUT状态的持续时间是最长分节生命周期(MSL)的两倍,即2MSL。RFC中的建议值是2分钟,Berkeley的实现传统上使用的是30秒,那么这意味着TIME_WAIT状态的延迟是在1~4分钟之间。
既然TIME_OUT状态的存在是有其意义的,为什么这么多人对其如此敏感,对于CS的模式,大多是由客户机主动关闭连接,这也避免了TIME_OUT产生于服务端,但对于某些协议,如HTTP则是由服务器执行主动关闭的。
TCP的SO_LINKGER 选项
相信只要提到TIME_OUT,SO_LINKGER就会现身,没错,该选项的设定控制着TCP的关闭形态,TCP默认是在close立即返回后,如果有数据残留在套接字的发送缓冲区中,系统将试着把这些数据发送给对端。
JDK对该选项的定义为:
public void setSoLinger(boolean on, int linger) throws SocketException;
两个参数将产生下列三种情形:
1、 on 为 false,则该选项关闭,linger 的值被忽略,这就是TCP的缺省设置,close立即返回,如果可能将会传输未发送的数据给对端;
2、 设置on为true,linger大于0(我在很多文章中看到这里写的是非0,但Java中,给该选项设置小于0会抛出” invalid value for SO_LINGER”异常)那么当close某个连接时,内核将拖延一段时间。即linger的时间(linger的单位为秒,最大值为65535)。这里的拖延(close 阻塞)是相对于BIO来讲,如果套接字先前被设置为非阻塞(NIO),那么将不等待close完成,即使linger > 0也是如此。如果套接字发送缓冲区中仍然残留数据,那么close线程将被投入睡眠,直到所有数据都已发送完,并且均被对端确认或者拖延时间到,close才会被唤醒。
这里有一个原则:设置SO_LINGER套接字选项后,close的成功返回只是告诉我们早先发送的数据(包括FIN)已由对端TCP确认,而不能告诉我们对端的应用进程是否已读取到数据,但如果不设置该套接字选项,那我们连对端TCP是否确认了数据都不知道;
3、 设置on为true,linger 为0,那么当close某个连接时,TCP夭折该连接。也就是说TCP将丢弃保留在发送缓冲区中的任何数据,仅仅给对端发送一个RST分节,而没有通常所说的四分组终止序列,这样一来避免了TIME_WAIT状态。
然而在2MSL秒内创建该连接的另一个化身,会导致老的重复分节被不正确地递送到新的化身上。这样的情况,有一个替代,就是TCP的 SO_REUSEADDR选项。
这个选项留到下一篇中详述
- 大小: 8.1 KB
分享到:
相关推荐
近期服务器出现大量time_wait的TCP连接造成服务器连接数过多而最终导致tomcat假死状态。连接服务器查看连接数的时候提示如下。 [root@test apache-tomcat-7.0.53]# netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a...
linux c 网络编程 测试tcp连接的TIME_WAIT状态 非常适合于初学者
减少Linux服务器过多的TIME_WAIT TIME_WAIT状态的意义: 客户端与服务器端建立TCP/IP连接后关闭SOCKET后,服务器端连接的端口 状态为TIME_WAIT 是不是所有执行主动关闭的socket都会进入TIME_WAIT状态呢? 有...
详细描述TCP的各个状态,初学者可以快速理解掌握tcp状态图
修改注册表中的tcpip的TIMEWAIT回收时间属性值,需要重启后生效 在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters,添加名为TcpTimedWaitDelay的DWORD键,设置为十进制0,以缩短TIME_WAIT...
个人简介文章分类全部博文(229)进程间通信(4)版本控制(9)个人计划(2)进程调度(0)文件系统/存储(3)内存管理(12)系统/脚本(3)编程相关(8)攻
LINUX 大量TIME_WAIT状态的连接解决方法
tcp连接是网络编程中最基础的概念,基于不同的使用场景,我们一般区分为“长连接”和“短...长短连接的优点和缺点这里就不详细展开了,有心的同学直接去google查询,本文主要关注如何解决tcp短连接的TIME_WAIT问题。
问题描述:在Linux系统中高并发的Squid服务器,TCP TIME_WAIT套接字数量经常达到两、三万,服务器很容易被拖死。解决方法:通过修改Linux内核参数,可以减少linux服务器的IME_WAIT套接字数量。vi /etc/sysctl.conf...
NULL 博文链接:https://bert82503.iteye.com/blog/2147899
netstat显示 TIME_WAIT 的原因及解决办法 netstat显示TCP连接进入TIME_WAIT状态的原因及解决办法
如果大量的 Time_wait ...使用 TCP Keepalive:TCP Keepalive 可以在服务器端和客户端之间建立持久连接,避免连接断开后导致的 TIME_WAIT 状态。 使用传输层网关:传输层网关可以代替服务器端和客户端之间的直接连接,
3.3 timestack数据包-Wireshark3.4 内核协议栈相关主要源码Time_wait状态生成及快速回收相关代码:开启timestamps引起的丢
摘要视图订阅01.02.03.04.05.06.162149次第9644名99篇1篇0篇30条【Linux网络编程笔记】TCP短连接产生大量TIME_WAIT导
4.2 客户的端口号和TIME_WAIT状态 43 4.3 设置TIME_WAIT状态的目的 45 4.4 TIME_WAIT状态的截断 48 4.5 利用TAO跳过三次握手 51 4.6 小结 55 第5章 T/TCP协议的实现:插口层 56 5.1 概述 56 5.2 常量 56 5.3 sosend...
4.2 客户的端口号和TIME_WAIT状态 43 4.3 设置TIME_WAIT状态的目的 45 4.4 TIME_WAIT状态的截断 48 4.5 利用TAO跳过三次握手 51 4.6 小结 55 第5章 T/TCP协议的实现:插口层 56 5.1 概述 56 5.2 常量 56 5.3 sosend...
1 检测web服务器的链接数量及状态: ...122 125.162.71.199 TIME_WAIT 99 79.119.125.43 TIME_WAIT 81 125.167.243.77 TIME_WAIT 75 110.137.106.75 TIME_WAIT 29 118.97.140.166 TIME_WAIT 29 115.192.
该模块允许丢弃TCP连接,可用于终止TIME-WAIT套接字。 用法 首先编译并加载模块: $ make $ sudo insmod drop-tcp-sock.ko 单插座杀死: # netstat -n -t | grep WAIT tcp 0 0 127.0.0.1:50866 127.0.0.1:22 ...
tcp几种状态和time_wait过高处理