近来网站随着访问量的增加,服务器的压力也随之上升,一个很明显的状况便是服务端产生了大量的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
分享到:
相关推荐
8. `net.ipv4.tcp_fin_timeout`:减少FIN-WAIT-2状态的持续时间,更快释放资源。 9. `net.ipv4.tcp_keepalive_probes`:减少超时前的探测次数,以减少无效连接的保持时间。 10. `net.core.netdev_max_backlog`:优化...
【TCP TIME_WAIT常见解决方法】 TCP TIME_WAIT状态是TCP连接生命周期中的一个重要阶段,它发生在主动关闭连接的一方(通常称为客户端)在连接关闭后等待一段时间,以确保所有在网络中可能残留的数据片段都被接收并...
在Linux系统中,进行网络编程时,TCP连接的TIME_WAIT状态是至关重要的一个环节。TIME_WAIT状态是TCP连接生命周期中的最后一个阶段,对于理解和优化网络应用性能有着直接的影响。本资源"TIME_WAIT.rar"包含了关于这个...
TIME_WAIT是TCP协议中的一个状态,当一个TCP连接正常关闭后,会进入TIME_WAIT状态,等待一段时间(通常是2MSL,即最大段生命周期的两倍)来确保网络中没有残留的数据包。在这个状态下,端口被占用,不能立即复用,这...
【Linux网络编程笔记】TCP短连接产生大量TIME_WAIT导致无法对外建立新TCP连接的原因及解决方法,这是一个关于网络编程和Linux系统配置的问题。在TCP/IP通信中,TIME_WAIT状态是TCP连接生命周期的一部分,用于确保...
TIME_WAIT是TCP连接的一个正常终止状态,但若数量过多则可能会影响到服务器性能。本文将详细介绍如何在Linux系统中优化TIME_WAIT状态的连接,并提供具体的配置示例。 #### TCP TIME_WAIT状态简介 TCP协议在连接...
当一个 TCP 连接关闭时,服务器端会在 TIME_WAIT 状态下等待一段时间,以确保所有的数据包都已经被客户端收到。在这个状态下,服务器端会等待两个最大段生命周期(Maximum Segment Lifetime,MSL)的时间,以确保...
在深入探讨如何有效释放TIME_WAIT状态的连接之前,我们首先需要理解TIME_WAIT状态的基本概念及其在TCP协议中的作用。TIME_WAIT是一种TCP连接的状态,当一个TCP连接被主动关闭时,客户端会进入TIME_WAIT状态,目的是...
在 TCP 连接中,客户端和服务器端都可以处于不同的状态,例如 ESTABLISHED、CLOSE_WAIT、FIN_WAIT_1、FIN_WAIT_2、TIME_WAIT 等 trạng thái。 CLOSE_WAIT 状态是 TCP 连接中的一种状态,它表示服务器端已经收到了...
Linux内核协议栈中的TCP协议在处理连接关闭时,会进入一个特定的状态叫做time_wait。这个状态对于确保TCP连接的可靠性和避免旧连接与新连接混淆至关重要。在time_wait状态下,连接不会立即关闭,而是等待一段时间,...
当我们看到netstat输出中存在大量的TCP连接处于TIME_WAIT状态时,这通常意味着系统可能存在一些性能问题或者配置上的挑战。本篇文章将深入探讨TIME_WAIT状态的原因以及如何解决。 TCP(传输控制协议)是一种面向...
4. `net.ipv4.tcp_fin_timeout = 30`:设置FIN_WAIT-2状态的持续时间,减少等待时间。 5. `net.ipv4.tcp_keepalive_time = 1200`:调整TCP空闲连接检查的频率,防止死连接占用资源。 6. `...
在Linux服务器环境中,当TCP/IP连接关闭后,服务器端的端口可能会进入TIME_WAIT状态,这是TCP协议设计的一部分。TIME_WAIT状态的目的是确保网络中不存在旧的、可能重复的数据包,从而避免对新连接造成干扰,并确保...
TIME_WAIT状态是TCP连接的四次挥手关闭协议中的一个重要状态,它存在的理由是为了确保TCP全双工连接的正常终止和避免老的重复分节在网络中消逝。 在TIME_WAIT状态中,客户端必须维持状态信息,以便在最后的ACK丢失...
4. **调整TIME_WAIT计时器**:在必要时,可以适当降低TIME_WAIT的等待时间,但要注意这可能会影响TCP的可靠性。 CLOSE_WAIT状态: CLOSE_WAIT状态发生在被动关闭连接的一方,即接收到对方的FIN包后,表示它已经收到...
使用netstat -na命令可以查看当前的TCP连接状态,包括LISTEN、ESTABLISHED、TIME_WAIT等状态。在这个例子中,使用netstat -na命令可以发现服务器端的连接状态为CLOSE_WAIT,这就表明服务器端的连接尚未释放。 通过...
修改注册表中的tcpip的TIMEWAIT回收时间属性值,需要重启后生效 在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters,添加名为TcpTimedWaitDelay的DWORD键,设置为十进制0,以缩短TIME_WAIT...
TCP连接有多种状态,包括LISTEN、SYN_SENT、SYN_RECEIVED、ESTABLISHED、CLOSE_WAIT、FIN_WAIT_1、FIN_WAIT_2、TIME_WAIT等。每个状态都代表了连接的不同生命周期阶段。Close_Wait是服务器端接收到客户端的FIN( ...
本文讨论了在线上环境中,服务端长连接和客户端短连接配置不当导致Nginx服务器产生大量“TIME_WAIT”状态线程的问题,同时提供了问题的分析和解决方法。本文主要涉及的网络编程知识点包括长连接与短连接的定义和区别...