服务端大量处于TIME_WAIT和CLOSE_WAIT状态连接的原因
- 1.服务端大量处于TIME_WAIT状态的连接原因?
- 1.HTTP没有使用长连接
- 2.HTTP长连接超时
- 3.HTTP长连接的请求数量达到上限
- TIME_WAIT状态连接过多的危害?
- 2.服务器大量处于CLOSE_WAIT状态的连接原因?
1.服务端大量处于TIME_WAIT状态的连接原因?
由四次挥手我们可以知道,TIME_WAIT状态是主动关闭连接方才会出现的状态。
为什么会有TIME_WAIT状态呐?
1.保证被动关闭连接的一方,能正确的关闭。
TCP主动关闭的那一方,发送的ACK报文可能丢失,这时对方就会重新发送FIN报文,如果没有这个状态的话,就不能正常的关闭连接了。
2.防止历史连接中的数据,被后面相同的四元组的连接错误的接收。
TCP在进行连接的时候可能会由于一些原因而造成延迟,假如说当进行连接的TCP报文延
迟的话,对方又会进行重传,之后进行正常的通信,当对方主动关闭的时候,恰好之前延
迟的连接报文到了,如果没有这个状态的话,那么服务端又会误以为这个是新的连接,这
样状态是为了保证延迟的报文在网络中消逝。
而当服务器有大量的TIME_WAIT状态的连接的话,则代表服务器主动断开了大量连接,而造成这种原因的情况有:
1.HTTP没有使用长连接
HTTP长连接(Keep-Alive)机制在HTTP/1.0中是默认关闭的,如果浏览器要开启Keep-Alive,它必须在请求的header中添加
Connection: Keep-Alive
而当服务器收到请求,如果支持长连接的话,则也响应的header中添加上面的信息。
从HTTP/1.1后,就默认开启了Keep-Alive。
在RFC文档中,并没有规定必须谁来主动关闭连接。
但是大多数Web服务器的实现都是由服务端主动关闭连接。
当客户端禁用了HTTP Keep-Alive,服务端开启Keep-Alive时,为什么要服务端主动关闭呐?
因为HTTP是请求-响应模型,当对方禁用了Keep-Alive时,就只有在服务端来关闭了。
当服务端禁用了HTTP Keep-Alive,客户端开启Keep-Alive时,为什么要服务端主动关闭呐?
如果是服务端主动关闭,则只需要调用close()就可以了,(一次系统调用的代价)
而如果是客户端主动关闭的话,则需要调用一次read(),然后获取到对方已关闭
连接,之后再调用close(),这个要花费两次系统调用的代价。
假如说服务端出现了大量TIME_WAIT状态的连接,这个时候我们可以查看一下客户端和服务端是否都开启了Keep-Alive。
2.HTTP长连接超时
为什么防止客户端完成一个HTTP请求后,占着资源不发起新的请求的行为,Web服务软件一般都会提供一个超时参数,当定时器时间一到,服务端就会主动断开连接。
这个时候我们可以排除一些网络问题,是否是因为网络,造成服务器一直收不到客户端的消息。
3.HTTP长连接的请求数量达到上限
Web服务器通常有个参数,就是同时处理HTTP长连接的请求数量,当连接数到达这个数量时,nginx就会主动关闭这个连接,造成服务端出现大量TIME_WAIT状态的连接。
这个时候,我们就可以适当的调整这个参数的值。
TIME_WAIT状态连接过多的危害?
1.占用系统资源,如:文件描述符,内存资源,CPU资源。
2.占用断开资源。
2.服务器大量处于CLOSE_WAIT状态的连接原因?
从上面的图我们可以知道,CLOSE_WAIT状态是被动关闭方才会出现的状态。
所以,当出现大量CLOSE_WAIT状态的连接时,说明服务端的程序没有调用close()函数关闭连接。
一般TCP服务端的流程
1.创建socket, bind端口,listen端口
2.将服务端socket注册到epoll
3.当连接到来时调用accpet获取连接的socket
4.将获取的socket注册到epoll
5.epoll_wait
3.假如对方关闭连接,则自己也关闭连接
假如说第4步当服务端把获取的socket注册到epoll上,或者第6步,当客户端关闭连接后,服务端由于某些原因没有执行close时,都会造成该原因。