한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

游戏卡顿白皮书 › TCP 重传的根本原因

连接中途 NAT/负载均衡器映射过期 NAT / load balancer mapping expired mid-connection

原因 ID rt-mapping · 主责 研发团队·客户端开发 · 配合 研发团队·服务器开发, 运维团队·网络运维, 运维团队·系统运维

在含图示和实验的完整版中打开此卡片 →

中间设备删掉空闲连接的映射(记录该连接应转发到哪里的条目)后,之后发出的包就送不到了。要么反复重传后掉线,要么设备回一个拒绝连接的 RST,立刻断开。

起因 一段时间内没有数据包往来的连接(暂离、大厅) → 结果 路由器 NAT、运营商 CGNAT、防火墙、负载均衡器、云安全组删除空闲映射 → 画面表现 再次操作的瞬间开始连续重传,然后掉线,或者直接掉线

症状
掉线, 卡住
因素
丢包
谁会遇到
只有我, 特定地区/运营商
何时出现
挂机一段时间后
负责方
主责 研发团队·客户端开发 · 配合 研发团队·服务器开发, 运维团队·网络运维, 运维团队·系统运维
研发团队要做的事
客户端:以不超过最短空闲超时一半的间隔发送心跳(玩家路由器和运营商 CGNAT 的映射只有靠从内往外发的包才能可靠刷新,超时时间我方也改不了,所以由客户端发送);断开后自动重连。服务器:响应心跳,一段时间收不到就主动清理连接(缩短 TCP keepalive 间隔(TCP_KEEPIDLE 等 socket 选项),用 TCP_USER_TIMEOUT 尽早发现);凭会话令牌接续会话。
运维团队要做的事
网络:汇总路径上各防火墙、负载均衡器的空闲超时,同步给研发团队;必要时调大我方防火墙、负载均衡器的超时。服务器/OS:确认云安全组的连接跟踪时间,同步给研发团队。
数值参考
各设备保留 TCP 映射的时间从几分钟到几小时不等。云安全组配置为跟踪连接时,AWS Nitro v6 实例类型默认 350 秒后删除跟踪条目(其他类型为 5 天,看“云安全组连接跟踪过期”)。Linux TCP keepalive 默认“空闲 2 小时才探测”,比大多数设备都晚。
监控图上
连接成批断开 · 断开次数、断开前的空闲时长
查看位置
用服务器侧抓包查看断开连接的最后几分钟;存活的连接用 ss -ti 的 lastsnd、lastrcv(距最后一次发送、接收经过的 ms)看空闲时间。同时看 nstat 的 TcpExtTCPAbortOnTimeout(因定时器到期而放弃连接的次数)
确认依据
每个断开的连接,断开前的空闲时间都超过了某个相近的值(路径上设备的空闲超时,例如 AWS Nitro v6 实例安全组的 350 秒);空闲后从第一个包起就收不到 ACK,只有重传,最后放弃,或立即收到 RST
排除依据
与空闲时间无关、游戏过程中也会断开,则是其他原因(“路径变更/ECMP 故障路径”“防火墙/连接跟踪丢包”)。心跳间隔不超过最短空闲超时一半的连接,可排除这个原因
确认手段
运维工具即可确认(无需游戏代码)

出处

  1. RFC 5382: NAT Behavioral Requirements for TCP IETF
    建议 TCP NAT 的空闲连接超时不少于 2 小时 4 分钟(以设备可能主动删除空闲会话为前提)
  2. RFC 4787: Network Address Translation (NAT) Behavioral Requirements for Unicast UDP IETF
    NAT 映射必须由从内往外发的包刷新(REQ-6),由从外进来的包刷新则是可选项(针对 UDP)
  3. Amazon EC2 security group connection tracking AWS
    TCP 空闲跟踪超时默认值:Nitro v6 实例类型 350 秒,其他类型 432,000 秒(5 天)。建议 keepalive 间隔短于 5 分钟
  4. IP Sysctl Linux kernel
    tcp_keepalive_time 默认 2 小时
  5. tcp(7) — Linux manual page Linux man-pages
    TCP_KEEPIDLE(开始 keepalive 前的空闲时间),TCP_USER_TIMEOUT(等待未确认数据多久后关闭连接)
  6. RFC 5482: TCP User Timeout Option IETF
    TCP 用户超时:发出的数据多久未被确认就关闭连接
  7. ss(8) — Linux manual page iproute2
    ss -i 的 lastsnd、lastrcv:距最后一次发送、接收经过的时间(ms)
  8. SNMP counter Linux kernel
    TcpExtTCPAbortOnTimeout:因 TCP 定时器到期、未发送 RST 就放弃的连接数

相关原因

同一层:TCP 重传的根本原因

其他层中同样导致“掉线”的原因

查看含图示和实验的原卡片