这篇文章将为大家详细讲解有关怎么对TCP的性能进行优化,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。
三次握手阶段
客户端SYN包的重试次数
<代码> sysctl - w net.ipv4。tcp_syn_retries=6 代码>
相关介绍
第1次重试发生在1秒钟后,接着会以翻倍的方式在第2、4、8、16、32秒共做6次重试,最后一次重试会等待64秒,如果仍然没有返回ACK,才会终止三次握手,所以,总耗时是1 + 2 + 4 + 8 + 16 + 32 + 64=127秒,超过2分钟。
服务端半连接池大小
<代码> sysctl - w net.ipv4。tcp_max_syn_backlog=16384 代码>
服务端半连接池满了以后是否开启syncookie机制
<代码> sysctl - w net.ipv4。tcp_syncookies=1 代码>
相关介绍
如果SYN半连接队列已满,默认会丢弃连接并不是这样,开启syncookies功能就可以在不使用SYN队列的情况下成功建立连接。
syncookies是这么做的:服务器根据当前状态计算出一个值,放在己方发出的SYN + ACK报文中发出,当客户端返回ACK报文时,取出该值验证,如果合法,就认为连接建立成功,如下图所示。
- <李>
0表示关闭该功能,
李> <李>2表示无条件开启功能,
李> <李>1则表示仅当SYN半连接队列放不下时,再启用它。
李>注意:由于syncookie仅用于应对SYN泛洪攻击(攻击者恶意构造大量的SYN报文发送给服务器,造成SYN半连接队列溢出,导致正常客户端的连接无法建立),这种方式建立的连接,许多TCP特性都无法使用,所以,应当把tcp_syncookies设置为1,仅在队列满时再启用。
服务端SYN + ACK包的重试次数
<代码> net.ipv4。tcp_synack_retries=5 代码>
相关介绍
tcp_synack_retries的默认重试次数是5次,与客户端重发SYN类似,它的重试会经历1,2,4,8,16秒,最后一次重试后等待32秒,若仍然没有收到ACK,才会关闭连接,故共需要等待63秒。
服务端全连接队列的大小
取决于最小值(积压,/proc/sys/net/core/somaxconn),在linux内核2.2版本以后,听函数的积压参数就可以设置接受队列的大小。
另外积压参数还受限于linux系统级的队列长度上限,当然这个上限阈值也可以通过somaxconn参数修改,somaxconn是内核的参数,默认是128 .
sysctl - w net.core。somaxconn=32768
四次挥手阶段
接下来我们把先关闭连接的一方叫做主动方,后关闭连接的一方叫做被动方。
四次挥手的流程:
其实四次挥手只涉及两种报文:鳍和ACK.FIN就是完成结束连接的意思,谁发出鳍报文,就表示它将不再发送任何数据,关闭这一方向的传输通道.ACK是承认确认的意思,它用来通知对方:你方的发送通道已经关闭。当主动方关闭连接时,会发送鳍报文,此时主动方的连接状态由建立变为FIN_WAIT1。当被动方收到鳍报文后,内核自动回复ACK报文,连接状态由建立变为CLOSE_WAIT,顾名思义,它在等待进程调用接近函数关闭连接。当主动方接收到这个ACK报文后,连接状态由FIN_WAIT1变为FIN_WAIT2,主动方的发送通道就关闭了。再来看被动方的发送通道是如何关闭的。当被动方进入CLOSE_WAIT状态时,进程的阅读函数会返回0,这样开发人员就会有针对性地调用接近函数,进而触发内核发送鳍报文,此时被动方连接的状态变为LAST_ACK。当主动方收到这个鳍报文时,内核会自动回复ACK,同时连接的状态由FIN_WAIT2变为TIME_WAIT, Linux系统下大约1分钟后TIME_WAIT状态的连接才会彻底关闭。而被动方收到ACK报文后,连接就会关闭。
主动方的优化
等待ACK,鳍包的重发次数
主动方发送鳍报文后,连接就处于FIN_WAIT1状态下,该状态通常应在数十毫秒内转为FIN_WAIT2。只有迟迟收不到对方返回的ACK时,才能用netstat命令观察到FIN_WAIT1状态。此时,内核会定时重发鳍报文,其中重发次数由tcp_orphan_retries参数控制(注意,孤儿虽然是孤儿的意思,该参数却不只对孤儿连接有效,事实上,它对所有FIN_WAIT1状态下的连接都有效),默认值是0,特指8次: