linux tcp重传由tcp_syn_retries、tcp_retries1、tcp_retries2分场景协同控制:tcp_syn_retries管syn发起重试(默认6次,弱网建议调至3–4),tcp_retries1触发路由探测(默认3),tcp_retries2决定已建立连接超时放弃时机(默认约924秒,非简单次数)。

Linux 中 TCP 重传次数不是单一参数控制的,而是由 tcp_syn_retries、tcp_retries1、tcp_retries2 三个参数分场景协同决定;盲目调大或调小都可能让连接在弱网下更快失败,或卡死更久。
tcp_syn_retries 控制 SYN 发起阶段的重试行为
这个参数只影响客户端主动发起连接时,SYN 包发出去后收不到 SYN-ACK 的重传次数。它不控制已建立连接的数据重传。
- 默认值通常是
6(部分发行版为5),对应超时时间按指数退避:1s、2s、4s、8s、16s、32s,第 6 次重传后若仍无响应,内核返回Connection timed out - 弱网环境(如高延迟、间歇性丢包的移动网络)下,设为
3或4更合理——避免等满 63 秒才报错,应用层能更快 fallback 或提示用户 - 不要设为
1:一次 SYN 就放弃,会把临时丢包误判为服务不可达;也不要设为0:无效值,内核会静默回退到默认值 - 修改方式:
echo 3 > /proc/sys/net/ipv4/tcp_syn_retries(临时)或写入/etc/sysctl.conf的net.ipv4.tcp_syn_retries = 3后执行sysctl -p(永久)
tcp_retries1 和 tcp_retries2 不是“重传次数上限”
这两个参数常被误解为“最多重传 N 次”,实际它们参与计算的是连接存活的总超时窗口,且逻辑完全不同。
Linux系统管理专家,覆盖12大模块:用户权限、SSH、存储、网络、systemd、防火墙、日志监控、备份恢复、TLS证书、Ansible、容器、IaC。提供配置、验证、加固、监控、备份、自动化、故障排查、回滚闭环。关键词:useradd、sudo、sshd_config、chmod、SEL...
-
tcp_retries1(默认3):触发路由探测的阈值。当连续3次 RTO 超时未确认,内核会怀疑当前路由失效,尝试更新路由表(比如查 FIB),但连接本身不终止 -
tcp_retries2(默认15):决定“活着的连接”何时彻底放弃。它不指定次数,而是参与推导一个理论 timeout 值(约 924 秒),最终连接会在某次 RTO 超过该值时被 kill。实际重传次数取决于 RTT 波动和指数退避节奏,可能远少于 15 次 - 弱网下调
tcp_retries2风险很大:设为5表面看是“5 次重传”,但实际可能导致连接在约 127 秒就断开(按 RFC 计算),对长连接、保活场景极不友好 - 真正需要调整弱网表现的,往往是
tcp_rmem、tcp_wmem和启用tcp_sack,而非硬砍tcp_retries2
别忽略应用程序自身的超时设置
内核重传机制再精细,也挡不住应用层提前放弃连接。
- 例如用
curl或 HTTP 客户端设置了--connect-timeout 5,即使内核配置允许重传 6 次(耗时 63 秒),应用也会在 5 秒后直接报错并关闭 socket - Java 的
Socket.connect()默认无 connect timeout,但很多框架(Spring Boot、OkHttp)自带默认值(常见 10–30 秒),会覆盖内核行为 - Node.js 的
net.Socket有setTimeout(),Go 的net.Dialer.Timeout同理——这些必须和内核参数对齐,否则调优毫无意义 - 验证方法:用
timeout 3s telnet 10.0.0.1 8080测试,比单纯看tcp_syn_retries更贴近真实行为
真正影响弱网体验的,从来不是“重传几次”,而是“每次重传间隔是否适应当前 RTT”以及“应用是否知道该等多久”。tcp_retries2 这类参数一旦改错,可能让连接在丢包恢复后仍被内核单方面终结——这种故障很难复现,也最难排查。










