如何提升TCP三次握手的性能?(涉及半连接、全连接)

TCP 三次握手就三个状态 :syn_sent、syn_rcv、established

一、客户端的优化

三次握手建立连接的首要目的是同步序列号。只有同步了序列号才有可靠的传输,TCP 协议的许多特性都是依赖序列号实现的,比如流量控制、消息丢失后的重发等等

客户端在等待服务器回复的 ACK 报文。正常情况下,服务器会在几毫秒内返回 ACK,但如果客户端迟迟没有收到 ACK 会怎么样呢?客户端会重发 SYN,重试的次数由tcp_syn_retries 参数控制,默认是 6 次。

优化:可以适当调低重试次数,尽快把错误暴露给应用程序

二、服务器端的优化

在SYN_RCV(RCV 是 received 的缩写)状态下,服务器必须建立一个 SYN 半连接队列来维护未完成的握手信息,当这个队列溢出后,服务器将无法再建立新连接。


新连接建立失败的原因有很多,怎样获得由于队列已满而引发的失败次数呢?netstat -s 命令给出的统计结果中可以得到队列溢出导致 SYN 被丢弃的个数

优化:调大 SYN 半连接队列

如果 SYN 半连接队列已满,只能丢弃连接吗?并不是这样,开启 syncookies 功能就可以在不使用 SYN 队列的情况下成功建立连接。syncookies 是这么做的:服务器根据当前状态计算出一个值,放在己方发出的 SYN+ACK 报文中发出,当客户端返回 ACK 报文时,取出该值验证,如果合法,就认为连接建立成功

由于 syncookie 仅用于应对SYN 泛洪攻击(攻击者恶意构造大量的 SYN 报文发送给服务器,造成 SYN 半连接队列溢出,导致正常客户端的连接无法建立),这种方式建立的连接,许多 TCP 特性都无法使用。所以,应当把 tcp_syncookies 设置为 1,仅在队列满时再启用。

服务器收到 ACK 后连接建立成功,此时,内核会把连接从 SYN 半连接队列中移出,再移入 accept 队列,等待进程调用 accept 函数时把连接取出来。如果进程不能及时地调用accept 函数,就会造成 accept 队列溢出,最终导致建立好的 TCP 连接被丢弃

TFO 技术绕过三次握手,使得 HTTP 请求减少了 1 个 RTT 的时间。Linux 下可以通过tcp_fastopen 参数开启该功能。

你可能感兴趣的:(如何提升TCP三次握手的性能?(涉及半连接、全连接))