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

游戏卡顿白皮书 › L7 服务器操作系统(内核)

服务器间连接的临时端口耗尽 Ephemeral port exhaustion (TIME_WAIT)

原因 ID so-ports · 主责 研发团队·服务器开发 · 配合 运维团队·系统运维

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

游戏服务器频繁地与 DB 或其他服务器建立短连接又断开时,断开的连接会在一段时间内占着端口,导致新连接打不开。

起因 每个请求都新建连接再关闭 → 结果 先关闭的一方要占着端口约 60 秒(Linux,TIME_WAIT 状态),可用端口耗尽 → 画面表现 内部请求失败,导致存盘失败、功能出错

症状
吞操作/回档, 连不上/无限加载
因素
丢包
谁会遇到
全服, 仅特定功能
何时出现
人多的时候
负责方
主责 研发团队·服务器开发 · 配合 运维团队·系统运维
研发团队要做的事
复用连接(连接池),不要每个请求都新建连接再关闭。
运维团队要做的事
扩大端口范围(ip_local_port_range);评估出站连接复用 TIME_WAIT(Linux tcp_tw_reuse);监控 TIME_WAIT 数量。
数值参考
Linux 默认端口范围(32768~60999)约 2.8 万个。向同一个目标地址每秒新建连接超过 470 次就会耗尽。Windows 默认端口约 1.6 万个(49152~65535),TIME_WAIT 也更长,耗尽得更快。
监控图上
触顶后走平 · TIME_WAIT socket 数、内部连接失败次数
查看位置
用 ss -tan state time-wait 按目标地址统计 TIME_WAIT socket,在游戏服务器日志里找 connect 失败(EADDRNOTAVAIL)
确认依据
发往同一目标(DB 等)的 TIME_WAIT 在临时端口范围(默认约 2.8 万个)附近走平,connect 以 EADDRNOTAVAIL 失败
排除依据
TIME_WAIT 很少,却只有出站到外部的连接失败,看“云 NAT 网关连接/端口上限”
确认手段
运维工具即可确认(无需游戏代码)
深入了解
Linux 的 TIME_WAIT 60 秒是内核里写死的值。调小名字相近的 tcp_fin_timeout,TIME_WAIT 也不会变短。

出处

  1. IP Sysctl Linux kernel
    ip_local_port_range 默认 32768~60999;tcp_tw_reuse;tcp_fin_timeout 是 FIN_WAIT_2 状态的保持时间
  2. include/net/tcp.h (Linux v6.12) Linux kernel
    TCP_TIMEWAIT_LEN(60*HZ):TIME_WAIT 约 60 秒是内核常量
  3. TCP/IP port exhaustion troubleshooting Microsoft
    Windows 动态端口默认 49152~65535,关闭的连接默认以 TIME_WAIT 占着端口 4 分钟
  4. ss(8) — Linux manual page iproute2
    用状态过滤条件 state time-wait 只看 TIME_WAIT socket
  5. connect(2) — Linux manual page Linux man-pages
    EADDRNOTAVAIL:临时端口范围内的端口都在使用中,无法建立连接

相关原因

同一层:L7 服务器操作系统(内核)

其他层中同样导致“吞操作/回档”的原因

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