可以,按公网 IP 跳变来改。正在传数据的连接靠tcp_retries2收口;空闲长连接靠 keepalive。tcp_retries2不要小于 8,这是 RFC 1122 的下限,大约 100 秒以上才放弃,再小会把弱网误判成断网。
sysctl-wnet.ipv4.tcp_syn_retries=3sysctl-wnet.ipv4.tcp_synack_retries=3sysctl-wnet.ipv4.tcp_retries1=3sysctl-wnet.ipv4.tcp_retries2=8sysctl-wnet.ipv4.tcp_orphan_retries=3sysctl-wnet.ipv4.tcp_keepalive_time=180sysctl-wnet.ipv4.tcp_keepalive_intvl=15sysctl-wnet.ipv4.tcp_keepalive_probes=3sysctl-wnet.ipv4.tcp_fin_timeout=30sysctl-wnet.ipv4.tcp_tw_reuse=1sysctl-wnet.ipv4.tcp_no_metrics_save=1| 参数 | 值 | 原因 |
|---|---|---|
tcp_syn_retries | 3 | 新建连接大约 15 秒失败,不再空等 2 分钟 |
tcp_synack_retries | 3 | 只影响本机监听端口,车机是客户端,影响很小,和上面对齐即可 |
tcp_retries1 | 3 | 大约 3 次重传后通知协议栈重新选路。这是 RFC 下限,不要再改小 |
tcp_retries2 | 8 | 已建立连接变成黑洞后,大约 100 秒以上放弃。默认 15 要十几分钟 |
tcp_orphan_retries | 3 | 本端已经 close、对端无响应的连接尽快清掉 |
tcp_keepalive_time | 180 | 空闲 3 分钟开始探测。你原来的 300 要将近 6 分钟才断开,偏慢 |
tcp_keepalive_intvl | 15 | 探测间隔 15 秒 |
tcp_keepalive_probes | 3 | 3 次无应答断开,空闲连接大约 225 秒超时 |
tcp_fin_timeout | 30 | FIN_WAIT2从默认 60 秒收到 30 秒 |
tcp_tw_reuse | 1 | 允许新连接复用TIME_WAIT,避免重连被旧四元组挡住 |
tcp_no_metrics_save | 1 | 失败连接不要把很大的 RTO 留给下一次连接,否则重连会更慢 |
Keepalive 只对设置了SO_KEEPALIVE的套接字生效。OkHttp、Cronet 默认不开,所以腾讯视频、汽水音乐主要还是靠tcp_retries2=8。
需要 root。重启后会丢,开机后再执行一次。
Linux tcp_retries2 重传间隔(RTO)
核心:指数退避,每次超时后 RTO 翻倍;但 Linux 有上限 tcp_rto_max(默认120s),到达上限后不再继续增大。官方文档里 924.6s 是理论理想值(初始RTO=200ms,TCP_RTO_MIN),不是真实网络下一定严格等于这个值。
理论序列(初始RTO=200ms,tcp_retries2=15)
| 重传轮次 | 本次RTO(等待多久才发起本次重传) | 累计耗时 |
|---|---|---|
| 1 | 200ms | 0.2s |
| 2 | 400ms | 0.6s |
| 3 | 800ms | 1.4s |
| 4 | 1600ms | 3.0s |
| 5 | 3200ms | 6.2s |
| 6 | 6400ms | 12.6s |
| 7 | 12800ms | 25.4s |
| 8 | 25600ms | 51.0s |
| 9 | 51200ms | 102.2s |
| 10 | 102400ms | 204.6s |
| 11 | 120000ms | 324.6s |
| 12 | 120000ms | 444.6s |
| 13 | 120000ms | 564.6s |
| 14 | 120000ms | 684.6s |
| 15 | 120000ms | 804.6s |
第16次RTO触发判定超时,总累计≈924.6s,内核关闭连接。
👉 从第11轮开始,RTO触达 tcp_rto_max=120s,后续每轮重传间隔固定120s,不再翻倍。
关键要点
RTO不是固定值,动态计算
RTO = SRTT + 4*RTTVAR,根据当前连接RTT实时算出;上面表格只是理论最小初始RTO=200ms的推演。真实网络RTT大,初始RTO就更大,很快触达120s上限,总超时会比924s更小。两个终止条件任一满足就断连
- 重传次数达到 tcp_retries2
- 累计超时时间超过理论最大超时(924.6s)
先到哪个就先断开,不是必须跑完15次。
RFC1122:R2(tcp_retries2对应的总超时)≥100s,对应
tcp_retries2 ≥8
tcp_retries2=8 理论总超时≈102s,刚好满足RFC下限。内核参数查看/配置
# 查看当前值cat/proc/sys/net/ipv4/tcp_retries2cat/proc/sys/net/ipv4/tcp_rto_max# 临时修改sysctlnet.ipv4.tcp_retries2=8容易踩坑区分
tcp_retries2:ESTABLISHED状态业务数据报文重传tcp_syn_retries:握手SYN报文重传tcp_synack_retries:服务端SYN+ACK重传tcp_orphan_retries:孤儿连接(socket已关闭,内核残留连接)重传
补充:业务侧替代方案(推荐优先)
全局改tcp_retries2影响整机所有TCP;应用层优先用TCP_USER_TIMEOUTsocket选项,单独控制单条连接超时,不影响全局内核参数。
如果你需要,我可以:
- 给出 tcp_retries2=8 / 10 的完整RTO序列表;
- 或者对比 tcp_retries2 和 TCP_USER_TIMEOUT 的风险差异。
> ##解决方案:
TCP 不能跟着公网 IP 迁移。地址一变,TBOX 用现有的 TboxService 通知车机,车机把网络 101 先报不可用再重新验证。应用收到 onLost 就会拆掉旧套接字,用新地址重连,不必干等重传。
车机侧超时只做兜底:
tcp_retries2=8 大约 100 秒才放弃。有 IP 变化通知时,恢复是秒级;没通知时,最多卡这 100 秒。
3. 想让长连接不断,只能加隧道
业务 TCP 不能跨公网 IP 迁移。要不断,就在 TBOX 和固定网关之间建隧道,把 IP 变化挡在隧道外面:
• IKEv2 开 MOBIKE,外网地址变了只更新隧道外层,内层连接不动。
• 或者 WireGuard,对端地址变化后马上重握手,内层会话保留。
没有这条隧道,腾讯视频、语音这些已经建立的连接,IP 一跳就必然断,只能重连