newlive 发表于 2016-6-16 11:06:34

如何让server服务器避免2MSL

一、TIME_WAIT状态带来的一些问题
   根据TCP协议,主动发起关闭的一方会进入TIME_WAIT状态,持续2MSL(每个TCP报文在网络内的最长时间,称为MSL )。如果关闭TCP连接的server端,这样server端就会进入TIME_WAIT状态,倘若server端关闭了大量的连接,就会存在大量的TIME_WAIT状态,维护这些状态会给server带来很大的负担,并且由于TIME_WAIT状态占用的一些端口号由于还没有被释放,导致服务器的端口不够用。
   在高并发短连接的server端,当server处理完client的请求后立刻close socket,此时会出现大量的TIME_WAIT状态,如果这时client再并发大量的连接,此时部分连接就极有可能了连接不上了。
   一般情况下,进入TIME_WAIT状态的一般情况下是客户端,大多服务器端一般都是执行被动关闭,不会进入TIME_WAIT状态,当服务器端关闭某个服务再重新启动时,也会进入TIME_WAIT状态的。
二、TIME_WAIT状态会占用什么
    其实占用的是一个五元组:协议、本地IP、本地端口、远程IP、远程端口。当一个client端向一个服务器建立了大量的连接之后,可能会耗尽可用的五元组。
三、server引发的TIME_WAIT如何处理
1.把系统的2MSL(240S)时间减少;
2. 让TIME_WAIT状态可以重用,这样即使TIME_WAIT状态占满了所有端口,也不会拒绝新的请求。net.ipv4.tcp_tw_reuse = 1表示开启重用,允许将TIME_WAIT sockets重新用于新的TCP连接;
3.让TIME_WAIT尽快回收。net.ipv4.tcp_tw_recycle = 1表示开启TCP连接中的TIME_WAIT sockets的快速回收;
4.用linger强制关闭,但是会导致数据丢失,调用setsockopt设置套接字的linger延时标志。
struct linger
{
   intl_onoff;       /* 0 = off, nozero = on */
   intl_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决定)。

追梦人456 发表于 2016-6-27 15:31:41

{:3_133:}{:3_133:}{:3_133:}
页: [1]
查看完整版本: 如何让server服务器避免2MSL