今天又看了一遍TCP的连接建立和释放,因为面试的时候被问住了,惨。具体问题是
TIME_WAIT是什么状态,怎么产生的,对服务有什么影响,如何消除?
根据TCP协议定义的4次握手断开连接规定,是发起socket主动关闭的一方 ,socket将进入TIME_WAIT状态。TIME_WAIT状态将持续2个MSL(Max Segment Lifetime),在Windows下默认为4分钟,即240秒。
TIME_WAIT状态下的socket不能被回收使用.
具体现象是对于一个处理大量短连接的服务器,如果是由服务器主动关闭客户端的连接,将导致服务器端存在大量的处于TIME_WAIT状态的socket, 甚至比处于Established状态下的socket多的多,严重影响服务器的处理能力,甚至耗尽可用的socket,停止服务。
统计在一台前端机上高峰时间TCP连接的情况,统计命令:# netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
使用命令:vi /etc/sysctl.conf
编辑文件,加入以下内容:
net.ipv4.tcp_syncookies = 1 (某些情况下该参数已启用)
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30
然后执行/sbin/sysctl -p让参数生效。
net.ipv4.tcp_syncookies = 1表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;
net.ipv4.tcp_tw_reuse = 1表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;
net.ipv4.tcp_tw_recycle = 1表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
net.ipv4.tcp_fin_timeout修改系統默认的TIMEOUT时间
修改之后,再用命令查看TIME_WAIT连接数
netstat -ae|grep “TIME_WAIT” |wc –l
发现大量的TIME_WAIT 已不存在,mysql进程的占用率很快就降下来的,网站访问正常。 不过很多时候,出现大量的TIME_WAIT状态的连接,往往是因为网站程序代码中没有使用mysql.colse(),才导致大量的mysql TIME_WAIT。
TIME_WAIT 表示主动关闭,CLOSE_WAIT 表示被动关闭1.三次握手
下图是使用wireshark抓包工具抓的数据,ARP从ip到MAC地址的转换,首先是ARP广播,然后机器报给路由主机,
首先是通过 SYN--->>>SYN+ACK---->>>ACK
TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接:
位码即tcp标志位,有6种标示:
SYN(synchronous同步)
ACK(acknowledgement 确认)
PSH(push传送)
FIN(finish结束)
RST(reset重置)
URG(urgent紧急)
Sequence number(顺序号码)
Acknowledge number(确认号码)
在上图中有 Seg=0 Ack=1 win=29200 Len=0 MSS=1460 SACK_PERM=1 WS=128
MSS(Maximum Segment Size)最大报文段长度:是指每一个TCP报文段中的数据字段的最大长度,而不是整个TCP报文段的最大长度,这一部分写在 选项 字段中,以后就按照这个数值传送数据,通信双方可以有不同的MSS值。设定这个参数 不是考虑接收缓存可能放不下TCP报文段中的数据,而是考虑网络的利用率,如果数据字段1字节,那么利用率很低,如果很大的话,就会在IP层分片,出错还需要重传,到接收端在组合这样开销很大,所以MSS应设定大些只要在IP层不需要分片就可以,
除了上述的协议外,还发现有2种协议LLMNR和NBNS协议比较多,下面解释这两个协议
NetBIOS Name Server(NBNS)
NetBIOS,为网络基本输入输出系统(英语:Network Basic Input/Output System)的缩写,它提供了OSI模型中的会话层服务,让在不同电脑上运行的不同程序,可以在局域网中,互相连接,以及分享数据。严格来说,NetBIOS不是一种网络协议,而是应用程序接口(API)。较古老的操作系统,使用IEEE 802.2与IPX/SPX协议,可以使用NetBIOS Frames协议或NetBIOS over IPX/SPX协议来运作。现代操作系统,多数都使用TCP/IP协议,则可通过NetBIOS over TCP/IP协议来相互通讯。NBNS是动态DNS的一种,Microsoft的NBNS实现称为WINS。另外,为了将虚拟的NetBIOS网络扩展到多个IP子网,WINS标准还引入了一个或者多个NBDD(NetBIOS Datagram Distribution) 服务器
NetBIOS提供了三种软件服务:
1.名称服务,包括名称登录与名称解析, 就是NBNS
2.数据报文服务
3.会话服务
LLMNR(Link-Local Multicast Name Resolution)为使用IPv4、IPv6或者同时使用这两种地址的设备提供了点对点名称解析服务,可以让同一子网中的IPv4和IPv6设备不需要WINS或DNS服务器就可以解析对方的名称,而这个功能是WINS和DNS都无法完全提供的。虽然WINS可以为IPv4提供客户端-服务器以及点对点名称解析服务,不过并不支持IPv6地址。至于DNS,虽然支持IPv4和IPv6地址,但必须通过专门的服务器才能提供名称解析服务。LLMNR通过在DNS名称解析服务不可用时提供解析服务,弥补了DNS的不足。
在DNS 服务器不可用时,DNS 客户端计算机可以使用本地链路多播名称解析 (LLMNR—Link-Local Multicast Name Resolution)(也称为多播 DNS 或 mDNS)来解析本地网段上的名称。例如,如果路由器出现故障,从网络上的所有 DNS 服务器切断了子网,则支持 LLMNR 的子网上的客户端可以继续在对等基础上解析名称,直到网络连接还原为止。
除了在网络出现故障的情况下提供名称解析以外,LLMNR 在建立临时对等网络(例如,机场候机区域)方面也非常有用。
为什么三次握手?
2.TCP使用窗口机制进行流量控制
3.数据传输结束后,通信的双方都可以释放连接,意思就是客户端可以主动释放连接,服务器端也可以主动释放连接,而不是只有客户端主动释放。出现错误的原因是只是单纯的看计算机网络的书和记住那个释放的图,导致定向思维认为只有客户端主动释放连接。由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
MSL(Maximum Segment Lifetime)最长报文段寿命,RFC793建议为2分钟,但是有点时间长了。
关闭行为是在发起方数据发送完毕之后,给对方发出一个FIN(finish)数据段。直到接收到对方发送的FIN,且对方收到了接收确认ACK之后,双方的数据通信完全结束,过程中每次接收都需要返回确认数据段ACK。
今天面试问到Time-Wait状态,是怎么回事?为什么在Time-Wait状态必须等待2MSL时间呢?
正确的回答: Time-Wait状态都可以存在于客户端和服务器端。主要有2个理由要设定2MSL时间:
1.为了保证192.168.91.141发送的最后一个ACK报文段能够到达192.168.91.1 。这个ACK报文段有可能丢失,因而使处在LAST-ACK状态的192.168.91.1收不到对自己发送的FIN+ACK报文段的确认。192.168.91.1会超时重传这个FIN+ACK报文段,而192.168.91.141就能在2MSL时间内收到这个重传的FIN+ACK报文段。接着192.168.91.141重传一次确认,重新启动2MSL计时器。最后,192.168.91.141和192.168.91.1都正常进入到CLOSED状态。如果192.168.91.141在TIME-WAIT状态不等一段时间的话,而是在发送完ACK报文段后立刻释放连接,那么就无法收到192.168.91.1重传的FIN+ACK报文段,因而也不会再发送一次确认报文段。这样,192.168.91.1就无法按照正常步骤进入CLOSED状态。
2.为了防止 已失效的连接请求报文段,A在发送完最后一个ACK报文段后,再经过时间2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样就可以使下一个新的连接中不会出现这种旧的连接请求报文段。B只要收到A发出的确认,就进入了CLOSED状态,同样,B在撤销相应的传输控制块TCB后,就结束了这次TCP连接