
一、SYN 报文重传次数
客户端优化:三次握手建立连接的首要目的是同步序列号,SYN 的全称就叫 Synchronize Sequence Numbers(同步序列号)。客户端发送SYN包,长时间没有收到SYN+ACK报文,则会重发SYN包,这时可以通过修改tcp_syn_retries参数,默认5次;
服务端优化:当服务端收到SYN包,服务端会立马回复SYN+ACK包,此时服务器出现了新连接,状态是SYN_RECV
,这时半连接队列溢出后,服务端就无法再建立新的连接。
SYN_RECV
是指被动打开后,接收到了客户端的SYN并发送了ACK时的状态,此连接会放入半连接队列来维护未完成的握手信息。再进一步接收到客户端的ACK就进入 ESTABLISHED 状态。

二、修改半连接队列长度
增大 tcp_max_syn_backlog 和 somaxconn,也就是增大 accept 队列。
1.3 SYN+ACK报文重传次数
如果 SYN 半连接队列已满,只能丢弃连接吗?
并不是这样,开启 syncookies 功能就可以在不使用 SYN 半连接队列的情况下成功建立连接。syncookies 的工作原理:服务器根据当前状态计算出一个值,放在己方发出的 SYN+ACK 报文中发出,当客户端返回 ACK 报文时,取出该值验证,如果合法,就认为连接建立成功,如下图所示。

accept 队列已满,只能丢弃连接吗?
丢弃连接只是 Linux 的默认行为,我们还可以选择向客户端发送 RST 复位报文,修改tcp_abort_on_overflow为1;
- 0:如果 accept 队列满了,那么 server 扔掉 client 发过来的 ack ;
- 1:如果 accept 队列满了,server 发送一个 RST 包给 client,表示废掉这个握手过程和这个连接;
三、绕过三次握手
TCP Fast Open 功能可以绕过三次握手,使得 HTTP 请求减少了 1 个 RTT 的时间,Linux 下可以通过tcp_fastopen 开启该功能,同时必须保证服务端和客户端同时支持。
RTT = 传播时延 + 排队时延 + 处理时延
网友评论