时间记录:2019-6-2
问题描述:笔者在进行压力测试的时候遇到了奇怪的问题,压力机的环境是win7的环境,在进行压力测试的时候发现了系统的端口一直被占用,无法释放开来,进行了接口的查找发现了大量的端口处于time_wait的状态,处于未被释放的状态,在这里进行总结下,以后续出现相关问题的查找。
从如下的几个问题下进行总结:
握手协议的状态,握手协议的链接过程,相关系统参数的调整以适应要求。
1:握手协议
握手协议包括三次握手和四次握手,三次握手协议是进行连接,四次握手是进行终止的,这里描述的是TCP的连接和断开的握手。
三次握手协议(连接)
指的是在发送数据的准备阶段,服务器端和客户端之间需要进行三次交互
第一次握手:客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的syn(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手,连接建立后,客户端和服务器就可以开始进行数据传输了。
注意: 这里如果只发送SYN报文后结束其余的握手不执行那么会造成队列的拥挤形成了
四次握手(终止):
由于TCP的半关闭(half-close)造成的,既然一个TCP连接是全双工的(即数据在两个方向上能同同时传递),因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
2:握手协议的链接过程
三次握手过程
1)请求端(通常被称为客户)发送一个SYN段指明客户打算连接的服务器的端口,以及初始序号(INS)
2)服务器发回包含服务器的出事序号的SYN报文段作为应答。同时,将确认序列号设置为客户的ISN加1以对客户的SYN报文段进行确认。一个SYN将占用一个序号。
3)客户必须将确认序号设置为服务器的ISN加1以对服务器的SYN报文段进行确认。
注意:这里有个小细节问题,在服务端接收到了客户端发送的SYN报文的时候,那么需要去处理这个问题,那么这时候服务器接收到了大量的连接请求的时候需要将需要处理的请求放置到一个队列中,如果队列超出了限制那么将请求失败,同样的请求连接结束的时候需要将这个连接放置到一个队列中。这里有一个半连接和全连接的说法。这里就要提及到backlog somaxconn 问题了,在linux内核参数中进行调整(一般情况下linux的初始参数设置是不满足要求的,需要自己进行调整),在后续介绍具体的调整。
四次握手协议过程
1)客户端发送一个FIN,用来关闭从客户端到服务器端的数据传送
2)服务器端收到FIN后返回一个ACK,确认序号为收到的序号加1
3)服务器端还返回一个FIN,服务器端关闭连接
4)客户端返回一个FIN,确认序号设置为收到序号加1
3:握手协议中的相关状态以及发生状态的时机
tcp状态变迁图
TCP正常连接建立和终止所对应的状态
从状态变迁和正常的连接和终止对应的图中可以看出对应的11个状态如下
CLOSED: 端口处于关闭的状态,未被启用
LISTEN: 端口启用,处于监听的状态(可以查看linux的listener函数)
SYN_SENT: 发送SYN报文状态
SYN_收到:接受到发送的SYN报文
ESTABLISHED: 完成三次的握手处于连接状态
CLOSE_WAIT: 客户机发起关闭时服务机的状态
LAST_ACK: 服务机发送ACK报文
FIN_WAIT_1: 客户机接受到SYN后发送FIN的状态
FIN_WAIT_2: 客户机接受到ACK后的状态
CLOSEING: 客户机收到FIN后的状态
TIME_WAIT: time_wai状态也叫做2MSL等待状态。每一个具体TCP实现必须选择一个报文段最大生存时间MSL(Maximum Segment Lifetime) 注意这个值在实现中常用值是30秒,一分钟,或2分钟,在进行压力测试的时候需要进行参数的调整,后续介绍具体的设置这个状态如果一直保持的话会造成端口的占用,造成假死的状态,在实际的开发中需要注意。
状态描述可以根据自己的理解和每一个报文的作用,结合跃迁图理解
注意:这里有一个细节问题,当我们的服务器的大量端口的连接处于time_wait状态的时候,此时的端口是不能进行使用的,那么我们怎么办呢,这里涉及复用和快速回收的内核参数的调整,在后续介绍使用。
以上所有的状态都可以在命令中查询使用netstat即可
C:\Users\Administrator>netstat
活动连接
协议 本地地址 外部地址 状态
TCP 192.168.31.182:49163 14.18.140.55:21567 CLOSE_WAIT
TCP 192.168.31.182:49165 125.90.93.186:http CLOSE_WAIT
TCP 192.168.31.182:49170 36.110.237.200:http ESTABLISHED
TCP 192.168.31.182:49241 180.163.238.137:http ESTABLISHED
TCP 192.168.31.182:49713 61.172.237.153:http CLOSE_WAIT
TCP 192.168.31.182:50064 223.252.199.69:6003 ESTABLISHED
TCP 192.168.31.182:50640 220.181.43.8:http ESTABLISHED
TCP 192.168.31.182:50955 61.155.190.117:https ESTABLISHED
TCP 192.168.31.182:50982 180.149.145.241:https CLOSE_WAIT
TCP 192.168.31.182:51036 115.231.41.46:https CLOSE_WAIT
从中可以看出本地地址使用的端口和进行链接外部地址以及其端口,还有对应的链接状态
注意: 我们在进行网络问题的排查时可以使用此进行查看客户机和服务器机的网络的端口使用情况。服务器端的端口使用时有限制的,我们也同样可以进行调节,后续介绍。还有小细节是端口的使用和服务器的网卡的带宽相互影响。当端口的使用数量过多的时候,但是你的服务器的带宽不够使用了,也是造成吞吐量的瓶颈(TPS),网卡相关的参数的调整可以使用ethtool或者mii-tool,根据机器的支持。
4:相关系统参数的调整描述
time_wait参数调整
win+R -> regedit 调出注册表
HKET_LOCAL_MACHINE/SYSTEM/CurrentControlSet/services/Tcpip/Parameters 路径下修改
TCPTimedWaitDelay 为自己需要的,通常设置为30(10进制)
如果未找到,自行创建DWORD,设置名称和数据即可
backlog somaxconn参数调整
vi /etc/sysctl.conf 进入配置文件(vi操作不做描述)
添加
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
具体的数值大小自行调整以满足需求
端口限制调整
端口调整包括客户机和服务机
客户机:
win+R -> regedit 调出注册表
HKET_LOCAL_MACHINE/SYSTEM/CurrentControlSet/services/Tcpip/Parameters 路径下修改
MaxUserPort 65534(10进制)
如果未找到,自行创建DWORD,设置名称和数据即可
服务机:
vi /etc/sysctl.conf 进入配置文件(vi操作不做描述)
添加
net.ipv4.ip_local_port_range 1025 65534
注意前端口是系统默认使用的端口不可使用
time_wait快速回收 复用
vi /etc/sysctl.conf 进入配置文件(vi操作不做描述)
添加
net.ipv4.tcp_tw_reuse = 1
1表示连接处于time_wait状态是可以被重复使用,0表示不可以
net.ipv4.tcp_tw_recycle = 1
1表示连接处于time_wait会被快速回收,而0表示不可以
重点注意
在nat网络下,如果重复使用会因为tcp_timestamps导致链接失败,生产环境下不建议进行修改
链接
时间记录:2019-6-4
来源:CSDN
作者:huoruilin
链接:https://blog.csdn.net/justinhuo/article/details/90744624