HTTP连接状态总结

TCP连接的生命周期,通常会有

三个阶段

  1. TCP三次握手
  2. 数据传送
  3. TCP四次挥手

从Google上扒了一张详细介绍各个阶段的产生的连接状态图
TCP状态转换图

三种数据包

  1. SYN(同步序列编号,Synchronize Sequence Numbers)该标志仅在三次握手建立TCP连接时有效
  2. ACK(确认编号,Acknowledgement Number)是对TCP请求的确认标志
  3. FIN(结束标志,FINish)用来结束一个TCP连接

三个问题

SYN Flood攻击

SYN攻击是一个典型的DDoS攻击。
在三次握手过程中,服务器发送SYN-ACK之后,收到客户端的ACK之前的TCP连接称为半连接(half-open connect)。
SYN攻击就是客户端在短时间内伪造大量不存在的IP地址,向服务器不断地发送SYN包,服务器回复ACK包,并等待客户的ACK从而建立连接。
由于源地址是不存在的,不会再发送ACK确认包,所以服务器需要不断的重发直至超时,这些伪造的SYN包将长时间占用未连接队列,资源耗尽(CPU满负荷或内存不足),让正常的业务请求连接不进来。
参考TCP洪水攻击(SYN Flood)的诊断和处理

CLOSE_WAIT

主动关闭的一方发出FIN包,被动关闭的一方响应ACK包,此时被动关闭的一方就进入了CLOSE_WAIT状态。
通常,CLOSE_WAIT状态在服务器停留时间很短,如果你发现大量的CLOSE_WAIT状态,那么就意味着被动关闭的一方没有及时发出FIN包,一般有可能是程序没有及时关闭socket。
注意 CLOSE_WAIT没有超时参数控制,如果不重启进程,那么这些状态的连接会永远占用资源。

TIME_WAIT

在关闭连接的时候,先发FIN包的一方执行的是主动关闭,后发FIN包的一方执行的是被动关闭。主动关闭的一方会进入TIME_WAIT状态,并且在此状态停留两倍的MSL时长。
MSL指的是报文段的最大生存时间,如果报文段在网络活动了MSL时间,还没有被接收,那么会被丢弃。关于MSL的大小,RFC 793协议中给出的建议是两分钟,不过实际上不同的操作系统可能有不同的设置,以Linux为例,通常是半分钟,两倍的MSL就是一分钟,也就是60秒。
比较有效的方案是连接采用keep-alive,尽可能不让服务端主动关闭连接。