本文目录导读:

tcp_synack_retries 是 Linux 内核中用于控制 TCP 三次握手的第二步(即服务端发送 SYN-ACK 后,等待客户端回复 ACK 时)的重试行为的关键参数。
它决定了服务端在发送 SYN-ACK 报文后,如果没有收到客户端的 ACK,最多会重试多少次。
下面分几个层面详细解释其工作机制、配置方法及实际影响。
核心机制
当服务端(如一个 Web 服务器)回复客户端的 SYN 并发送 SYN-ACK 后,会启动一个定时器等待客户端的 ACK。
- 失败原因: 客户端可能由于网络问题、半连接队列(SYN Backlog)已满、或者直接拒绝连接(RST),没有回复 ACK。
- 重试过程:
- 服务端发送第一个 SYN-ACK。
- 等待超时(这个超时时间不是固定的,通常第一次是 1 秒,之后会指数退避,1s、2s、4s...)。
- 超时后,
tcp_synack_retries未耗尽,则重传 SYN-ACK。 - 重复步骤 2-3,直到达到
tcp_synack_retries设定的最大重试次数。 - 如果所有重试均失败,服务端会移除该半连接并返回一个 ETIMEDOUT 或类似的错误给应用层(如果有监听 socket)。
重要区别: 请不要把它和 tcp_syn_retries 搞混。tcp_syn_retries 是客户端发送 SYN 时重试的次数。
默认值
- 系统默认值: 通常为 5(在较新的内核中可能是 5,旧版可能是 3 或 6)。
- 查看当前值:
sysctl net.ipv4.tcp_synack_retries
数值的含义与影响
假设 tcp_synack_retries = 5,并且我们假设一个近似的重试间隔(实际内核实现可能略有不同):
| 重试次数 | 行为 | 距离第一次尝试的时间(近似) |
|---|---|---|
| 0 | 发送第一个 SYN-ACK | 0 秒 |
| 1 | 第一次重试 | 约 1 秒 |
| 2 | 第二次重试 | 约 3 秒 (1+2) |
| 3 | 第三次重试 | 约 7 秒 (3+4) |
| 4 | 第四次重试 | 约 15 秒 (7+8) |
| 5 | 第五次重试 | 约 31 秒 (15+16) |
| 失败 | 连接超时,释放资源 | 约 63 秒 |
tcp_synack_retries = 5 意味着服务端会花费大约 63 秒 来等待一个最终不存在的客户端 ACK。
如何配置它
-
临时修改(立即生效,重启后失效):
sudo sysctl -w net.ipv4.tcp_synack_retries=3
-
永久修改(写入配置文件): 编辑
/etc/sysctl.conf或/etc/sysctl.d/99-custom.conf文件,添加或修改:net.ipv4.tcp_synack_retries = 3
然后运行
sudo sysctl -p使其生效。
应用场景与调优建议
高并发服务器(如 Web Server、API Server)
- 问题: 默认值 5 会使服务端为每个“半连接”等待约 63 秒,如果遭受 SYN Flood 攻击或遇到大量客户端掉线,半连接队列会迅速被耗尽。
- 调优: 建议降低到 1 或 2。
tcp_synack_retries = 2会让等待时间缩短到大约 7-10 秒。- 原因: 正常的客户端配置通常在 1-2 秒内发送 ACK,3 秒内没有 ACK,很可能是恶意或无效请求,尽早丢弃这些连接可以保护服务器资源。
移动网络或不稳定网络环境(如 IoT 设备)
- 问题: 客户端信号不好,ACK 可能延迟很久。
- 调优: 可能需要增加到一个较高值,5 或 7。
- 原因: 确保在极其不稳定的网络下,连接仍然能建立成功,但代价是服务器资源占用时间变长。
防御 SYN Flood 攻击
tcp_synack_retries本身不是主要防御手段(那是 SYN Cookie 和 SYN Backlog 的职责),但降低它可以缓解其副作用。- 如果攻击者发送海量虚假 SYN,服务端会创建大量半连接并尝试重试 SYN-ACK,降低重试次数可以让这些伪造的连接更快被清理。
与其他参数的关系
tcp_synack_retries 并不是孤立生效的,它与以下参数紧密配合:
-
net.ipv4.tcp_syncookies- 当半连接队列(
tcp_max_syn_backlog)满了之后,SYN Cookie 机制会启用,服务端不会再为 SYN 创建半连接记录,而是直接计算一个 cookie 作为 SEQ 号返回,但即使启用了 SYN Cookie,tcp_synack_retries仍然有效 —— 只是在 Cookie 模式下,超时重试的逻辑可能稍有不同,但总体目的还是为了等待 ACK 的到来。
- 当半连接队列(
-
net.ipv4.tcp_abort_on_overflow- 这个参数决定了当监听队列(
accept queue)满时,是否直接发送 RST 给客户端,如果开启了,可能会导致客户端过早收到 RST,但通常不推荐开启。
- 这个参数决定了当监听队列(
tcp_synack_retries控制服务端在三次握手第二阶段的重试行为。- 默认值 5(约 63 秒超时)适合稳定、低并发的场景。
- 高并发服务器应降低至 1-3,以快速清理无效的半连接。
- 极端不稳定的网络可能需要保留高值,但需谨慎考虑资源消耗。
- 配合
tcp_syncookies和tcp_max_syn_backlog使用效果更佳。
最后一个小提示:如果你发现服务器上有大量 SYN_RECV 状态的连接,排查时首先要检查的是 半连接队列是否满(netstat -s | grep "SYNs to LISTEN" 或 ss -lnt 'sport = :80' | wc -l),tcp_synack_retries 只是影响这些连接存活的时长。