如何让server避免2MSL

1.首先根据TCP协议,主动发起关闭的一方会进入TIME_WAIT状态,持续2MSL.

对于基于TCP的HTTP协议,如果关闭TCP连接的是Server端,这样,Server端会进入TIME_WAIT状态,对于访问量大的Web Server,会存在大量的TIME_WAIT状态,假如server一秒钟接收1000个请求,那么就会积压240*1000=240000个TIME_WAIT的记录,维护这些状态给Server带来很大的负担,并且由于TIME_WAIT状态占用的一些端口由于还没有被释放可能还会导致服务器端口不够用。当然现代操作系统都会用快速的查找算法来管理这些TIME_WAIT,所以对于新的TCP连接请求,判断系统中是否有一个TIME_WAIT不会太费时间,但是有这么多状态要维护总是不好。

2.TIME_WAIT 状态到底会占用什么?
    被占用的是一个五元组:(协议,本地IP,本地端口,远程IP,远程端口)。对于 Web 服务器,协议是 TCP,本地 IP 通常也只有一个,本地端口默认的 80 或者 443。只剩下远程 IP 和远程端口可以变了。如果远程 IP 是相同的话,就只有远程端口可以变了。这个只有几万个,所以当同一客户端向服务器建立了大量连接之后,会耗尽可用的五元组导致问题。

在高并发短连接的server端,当server处理完client的请求后立刻close socket此时会出现TIME_WAIT状态然后如果client再并发2000个连接,此时部分连接就连接不上了。

3.如何消除大量TCP短连接引发的TIME_WAIT?

1)可以改为长连接,但代价较大,长连接太多会导致服务器性能问题,而且PHP等脚本语言,需要通过proxy之类的软件才能实现长连接;

2)修改ipv4.ip_local_port_range,增大可用端口范围,但只能缓解问题,不能根本解决问题;
3)客户端程序中设置socket的SO_LINGER选项;
4)客户端机器打开tcp_tw_recycle和tcp_timestamps选项;
5)客户端机器打开tcp_tw_reuse和tcp_timestamps选项;
6)客户端机器设置tcp_max_tw_buckets为一个很小的值
So_linger的作用
struct linger {
     int l_onoff; /* 0 = off, nozero = on */
     int l_linger; /* linger time */
};
其取值和处理如下:

1、设置 l_onoff为0,则该选项关闭,l_linger的值被忽略,等于内核缺省情况,close调用会立即返回给调用者,如果可能将会传输任何未发送的数据;
2、设置 l_onoff !=0 && l_linger = 0,则套接口关闭时TCP将断开连接,TCP将丢弃保留在套接口发送缓冲区中的任何数据并发送一个RST给对方,而不是通常的四分组终止序列,这避免了TIME_WAIT状态;
3、设置 l_onoff != 0 && l_linger != 0,当套接口关闭时内核将拖延一段时间(由l_linger决定)。

1、 若设置了SO_LINGER(亦即linger结构中的l_onoff域设为非零),并设置了零超时间隔,则closesocket()不被阻塞立即执行,不论是否有排队数据未发送或未被确认。这种关闭方式称为 “强制”或“失效”关闭 ,因为套接口的虚电路立即被复位,且丢失了未发送的数据。在远端的recv()调用将以WSAECONNRESET出错。 
2、 若设置了SO_LINGER并确定了非零的超时间隔,则closesocket()调用阻塞进程,直到所剩数据发送完毕或超时。这种关闭称为 “优雅”或“从容”关闭 。请注意如果套接口置为非阻塞且SO_LINGER设为非零超时,则closesocket()调用将以WSAEWOULDBLOCK错误返回。 
3、 若在一个流类套接口上设置了SO_DONTLINGER(也就是说将linger结构的l_onoff域设为零),则closesocket()调用立即返回。但是,如果可能,排队的数据将在套接口关闭前发送。请注意,在这种情况下WINDOWS套接口实现将在一段不确定的时间内保留套接口以及其他资源,这对于想用所以套接口的应用程序来说有一定影响。

TCP要保证在所有可能的情况下使得所有的数据都能够被投递。当你关闭一个socket时,主动关闭一端的socket将进入TIME_WAIT状态,而被动关闭一方则转入CLOSED状态,这的确能够保证所有的数据都被传输。当一个socket关闭的时候,是通过两端互发信息的四次握手过程完成的,当一端调用close()时,就说明本端没有数据再要发送了。这好似看来在握手完成以后,socket就都应该处于关闭CLOSED状态了。但这有两个问题,首先,我们没有任何机制保证最后的一个ACK能够正常传输,第二,网络上仍然有可能有残余的数据包(wandering duplicates),我们也必须能够正常处理。

通过正确的状态机,我们知道双方的关闭过程如下:

假设最后一个ACK丢失了,服务器会重发它发送的最后一个FIN,所以客户端必须维持一个状态信息,以便能够重发ACK;如果不维持这种状态,客户端在接收到FIN后将会响应一个RST,服务器端接收到RST后会认为这是一个错误。如果TCP协议能够正常完成必要的操作而终止双方的数据流传输,就必须完全正确的传输四次握手的四个节,不能有任何的丢失。这就是为什么socket在关闭后,仍然处于 TIME_WAIT状态,因为他要等待以便重发ACK。



时间: 2024-10-26 03:27:21

如何让server避免2MSL的相关文章

如何让server服务器避免2MSL

一.TIME_WAIT状态带来的一些问题 根据TCP协议,主动发起关闭的一方会进入TIME_WAIT状态,持续2MSL(每个TCP报文在网络内的最长时间,称为MSL ).如果关闭TCP连接的server端,这样server端就会进入TIME_WAIT状态,倘若server端关闭了大量的连接,就会存在大量的TIME_WAIT状态,维护这些状态会给server带来很大的负担,并且由于TIME_WAIT状态占用的一些端口号由于还没有被释放,导致服务器的端口不够用. 在高并发短连接的server端,当s

sever如何避免2MSL

一. 根据TCP协议,主动发起关闭的一方,会进入TIME_WAIT状态,持续2MSL,RFC 793建议MSL设置为两分钟. 为什么time_wait需要2*MSL等待时间? MSL就是maximum segment lifetime(最大分节生命期),这是一个IP数据包能在互联网上生存的最长时间,超过这个时间将在网络中消失. 假设最终的 ACK 丢失 , server 将重发 FIN , client 必须维护 TCP 状态信息以便可以重发最终的 ACK ,否则会发送RST ,结果 serve

解决Can't connect to MySQL server on 'localhost' (10048)

解决Can't connect to MySQL server on 'localhost' (10048) 您使用的是Windows操作系统,此错误与一个注册表键值TcpTimedWaitDelay有关.减小Windows中TcpTimedWaitDelay时间可解决此类问题,默认情况下为240(未设置的情况下也是这个数值) 此项设置需要到注册表如下位置进行设置HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Tcpip/Paramete

解决 2003 Can’t connect to MySQL server on ‘localhost’ (10048)

2003 Can’t connect to MySQL server on ‘localhost’ (10048)一般见于使用mysql的windows 2003服务器.错误的出现的原因: 第一种原因:应用程序需要快速释放和创建新连接, 但是由于 TIME_WAIT 中存在的连接超过默认值,导致较低吞吐量.解决方案:和本错误密切相关的两个windows的注册表项:TcpTimedWaitDelay和MaxUserPort的值.TcpTimedWaitDelay 确 定 TCP/IP 可释放已关闭

TCP连接的状态与关闭方式及其对Server与Client的影响

1. TCP连接的状态 首先介绍一下TCP连接建立与关闭过程中的状态.TCP连接过程是状态的转换,促使状态发生转换的因素包括用户调用.特定数据包以及超时等,具体状态如下所示: CLOSED:初始状态,表示没有任何连接.LISTEN:Server端的某个Socket正在监听来自远方的TCP端口的连接请求.SYN_SENT:发送连接请求后等待确认信息.当客户端Socket进行Connect连接时,会首先发送SYN包,随即进入SYN_SENT状态,然后等待Server端发送三次握手中的第2个包.SYN

TCP连接的状态与关闭方式,及其对Server与Client的影响

1. TCP连接的状态 首先介绍一下TCP连接建立与关闭过程中的状态.TCP连接过程是状态的转换,促使状态发生转换的因素包括用户调用.特定数据包以及超时等,具体状态如下所示: CLOSED:初始状态,表示没有任何连接. LISTEN:Server端的某个Socket正在监听来自远方的TCP端口的连接请求. SYN_SENT:发送连接请求后等待确认信息.当客户端Socket进行Connect连接时,会首先发送SYN包,随即进入SYN_SENT状态,然后等待Server端发送三次握手中的第2个包.

tcp四次挥手为什么要等待2MSL

之前所说了解有两个原因: 1.防止客户端最后一次发给服务器的确认在网络中丢失以至于客户端关闭,而服务端并未关闭,导致资源的浪费. 2.等待最大的2msl可以让本次连接的所有的网络包在链路上消失,以防造成不必要的干扰. 但对于第二条造成不必要的干扰之前没有做过多的解读,今天在网上查了下,顺便给大家分享下: 如果client直接closed,然后又向server发起了一个新连接,我们不能保证这个新连接和刚关闭的连接的端口号是不同的.假设新连接和已经关闭的老端口号是一样的,如果前一次滞留的某些数据仍然

Windows Server定时重启任务制定

[本篇以Windows Server 2012 R2为例] 第一步:编写重启脚步 其实就是一句话:shutdown /r 其他shutdown命令参考可以使用shutdown /?查阅 第二步:设置任务计划程序 1.再开始-所有应用中找到任务计划程序 2.展开任务计划程序库,这里对任务计划程序做了很多的分类,我们找到System Manager类,在此类下创建自动重启系统任务 3.选择窗口右侧的创建任务(也可以使用创建基本任务,它是以向导的方法创建) 4.常规页面用于定义任务名称及执行任务的用户

SQL Server 2008的MSSQLSERVER 请求失败或服务未及时响应

我的是SQL server 2008R2, 以前可以正常的启动SQL server(SQLEXPRESS).SQL server(MSSQLSERVER),有几天没有打开了,就在昨天 开机之后就无法启动MSSQLSERVER了,提示的信息如下图: 快速解决办法如下: 第一步:打开事件查看器,查看windows日志,点击应用程序,查看windows错误日志 http://product.pconline.com.cn/itbk/software/win8/1211/3060037.html 第二步