DDR爱好者之家 Design By 杰米

三次握手阶段

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

TCP性能调优实现原理及过程解析

服务端半连接池满了以后是否开启syncookie机制

sysctl -w net.ipv4.tcp_syncookies=1

相关介绍

如果 SYN 半连接队列已满,默认会丢弃连接并不是这样,开启 syncookies 功能就可以在不使用 SYN 队列的情况下成功建立连接。

syncookies 是这么做的:服务器根据当前状态计算出一个值,放在己方发出的 SYN+ACK 报文中发出,当客户端返回 ACK 报文时,取出该值验证,如果合法,就认为连接建立成功,如下图所示。

TCP性能调优实现原理及过程解析

  • 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 秒。

服务端全连接队列的大小

取决于min(backlog, /proc/sys/net/core/somaxconn),在linux内核2.2版本以后,listen 函数的 backlog 参数就可以设置 accept 队列的大小。

另外backlog 参数还受限于 Linux 系统级的队列长度上限,当然这个上限阈值也可以通过 somaxconn 参数修改,somaxconn是内核的参数,默认是128。

sysctl -w net.core.somaxconn=32768

四次挥手阶段

接下来我们把先关闭连接的一方叫做主动方,后关闭连接的一方叫做被动方。

四次挥手的流程:

其实四次挥手只涉及两种报文:FIN 和 ACK。FIN 就是 Finish 结束连接的意思,谁发出 FIN 报文,就表示它将不再发送任何数据,关闭这一方向的传输通道。ACK 是 Acknowledge 确认的意思,它用来通知对方:你方的发送通道已经关闭。当主动方关闭连接时,会发送 FIN 报文,此时主动方的连接状态由 ESTABLISHED 变为 FIN_WAIT1。当被动方收到 FIN 报文后,内核自动回复 ACK 报文,连接状态由 ESTABLISHED 变为 CLOSE_WAIT,顾名思义,它在等待进程调用 close 函数关闭连接。当主动方接收到这个 ACK 报文后,连接状态由 FIN_WAIT1 变为 FIN_WAIT2,主动方的发送通道就关闭了。再来看被动方的发送通道是如何关闭的。当被动方进入 CLOSE_WAIT 状态时,进程的 read 函数会返回 0,这样开发人员就会有针对性地调用 close 函数,进而触发内核发送 FIN 报文,此时被动方连接的状态变为 LAST_ACK。当主动方收到这个 FIN 报文时,内核会自动回复 ACK,同时连接的状态由 FIN_WAIT2 变为 TIME_WAIT,Linux 系统下大约 1 分钟后 TIME_WAIT 状态的连接才会彻底关闭。而被动方收到 ACK 报文后,连接就会关闭。

TCP性能调优实现原理及过程解析

主动方的优化

等待ACK,FIN包的重发次数

主动方发送 FIN 报文后,连接就处于 FIN_WAIT1 状态下,该状态通常应在数十毫秒内转为 FIN_WAIT2。只有迟迟收不到对方返回的 ACK 时,才能用 netstat 命令观察到 FIN_WAIT1 状态。此时,内核会定时重发 FIN 报文,其中重发次数由 tcp_orphan_retries 参数控制(注意,orphan 虽然是孤儿的意思,该参数却不只对孤儿连接有效,事实上,它对所有 FIN_WAIT1 状态下的连接都有效),默认值是 0,特指 8 次:

net.ipv4.tcp_orphan_retries = 0

孤儿连接的数量

net.ipv4.tcp_max_orphans = 16384

相关介绍

tcp_max_orphans 定义了孤儿连接的最大数量。当进程调用 close 函数关闭连接后,该连接是在 FIN_WAIT1 状态,这个连接都与该进程无关了,它变成了孤儿连接。Linux 系统为防止孤儿连接过多,导致系统资源长期被占用,就提供了 tcp_max_orphans 参数。如果孤儿连接数量大于它,新增的孤儿连接将不再走四次挥手,而是直接发送 RST 复位报文强制关闭。

孤儿连接的定义:由进程调用close关闭的连接称为孤儿连接,另外shutdown 函数也可以关闭连接,这二者都会向对方发送 FIN 报文(shutdown 参数须传入 SHUT_WR 或者 SHUT_RDWR 才会发送 FIN),区别在于 close 调用后,哪怕对方在半关闭状态下发送的数据到达主动方,进程也无法接收。如果你用 netstat -p 命令,会发现连接对应的进程名为空(与进程无关!)。而 shutdown 函数调用后,即使连接进入了 FIN_WAIT1 或者 FIN_WAIT2 状态,它也不是孤儿连接,进程仍然可以继续接收数据。

等待FIN的时间

net.ipv4.tcp_fin_timeout = 60

相关介绍

当连接收到 ACK 进入 FIN_WAIT2 状态后,就表示主动方的发送通道已经关闭,接下来将等待对方发送 FIN 报文,关闭对方的发送通道。这时,如果连接是用 shutdown 函数关闭的,连接可以一直处于 FIN_WAIT2 状态。但对于 close 函数关闭的孤儿连接,这个状态不可以持续太久,而 tcp_fin_timeout 控制了这个状态下连接的持续时长。

TIME_WAIT相关参数

相关介绍

TIME_WAIT 是主动方四次挥手的最后一个状态。当收到被动方发来的 FIN 报文时,主动方回复 ACK,表示确认对方的发送通道已经关闭,连接随之进入 TIME_WAIT 状态,等待 60 秒后关闭。

TIME_WAIT状态最大连接数

当 TIME_WAIT 的连接数量超过该参数时,新关闭的连接就不再经历 TIME_WAIT 而直接关闭。

net.ipv4.tcp_max_tw_buckets = 5000

是否复用TIME_WAIT状态的端口

复用 TIME_WAIT 状态的端口,如果服务器会主动向上游服务器发起连接的话,就可以把 tcp_tw_reuse 参数设置为 1,它允许作为客户端的新连接,在安全条件下使用 TIME_WAIT 状态下的端口。

net.ipv4.tcp_tw_reuse = 1

当然,要想使 tcp_tw_reuse 生效,还得把 timestamps 参数设置为 1,它满足安全复用的先决条件(对方也要打开 tcp_timestamps ):

net.ipv4.tcp_timestamps = 1

老版本的 Linux 还提供了 tcp_tw_recycle 参数,它并不要求 TIME_WAIT 状态存在 60 秒,很容易导致数据错乱,不建议设置为 1。

net.ipv4.tcp_tw_recycle = 0

所以在 Linux 4.12 版本后,直接取消了这一参数。

其他配置

允许系统打开的端口范围

sysctl -w net.ipv4.ip_local_port_range=1024 65000

系统全局允许分配的最大文件句柄数

sysctl -w fs.file-max=2097152

sysctl -w fs.nr_open=2097152

echo 2097152 > /proc/sys/fs/nr_open

允许当前会话或进程打开文件句柄数

ulimit -n 1048576

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

DDR爱好者之家 Design By 杰米
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
DDR爱好者之家 Design By 杰米

稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!

昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。

这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。

而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?