
tcp_tw_reuse 必须设为 1 才能缓解 Workerman 端口耗尽
Workerman 作为常驻进程的 PHP 长连接服务,在高频主动建连(如调用下游 HTTP API、Redis、MySQL)时,会大量产生 TIME_WAIT 连接。默认 net.ipv4.tcp_tw_reuse 是 0,内核禁止复用这些端口,直接导致 Cannot assign requested address 错误——这不是代码问题,是内核拒绝分配新端口。
必须将该值设为 1:
- 临时生效:
sysctl -w net.ipv4.tcp_tw_reuse=1 - 永久生效:在
/etc/sysctl.conf或/etc/sysctl.d/99-workerman.conf中写入net.ipv4.tcp_tw_reuse = 1,再执行sysctl -p(若配置在sysctl.d/下则用sysctl --system) - 验证是否生效:
sysctl net.ipv4.tcp_tw_reuse输出应为net.ipv4.tcp_tw_reuse = 1
tcp_tw_reuse 不起作用?先检查 tcp_timestamps
tcp_tw_reuse 依赖 TCP 时间戳选项做安全校验:新连接的 SYN 时间戳必须大于旧连接 FIN 的时间戳。如果 net.ipv4.tcp_timestamps 被关掉(值为 0),tcp_tw_reuse 就完全失效,哪怕你设了 1 也没用。
确认并修复:
- 运行
sysctl net.ipv4.tcp_timestamps,输出应为1 - 如果不是,加一行
net.ipv4.tcp_timestamps = 1到 sysctl 配置文件,再sysctl -p - 注意:该参数默认开启,但某些加固脚本或容器镜像可能手动关闭过
ip_local_port_range 和 tcp_tw_reuse 必须配合调整
只开 tcp_tw_reuse 不够。Workerman 主动发起连接时,可用本地端口范围太窄(默认 32768 65535,仅约 3.2 万个),即使复用,高并发下仍不够用。
建议扩到全可用范围(避开特权端口):
- 设为
net.ipv4.ip_local_port_range = 1024 65535(共约 6.4 万个端口) - 避免设成
1 65535:端口 1–1023 是特权端口,普通用户进程无法绑定,反而浪费空间 - 修改后需
sysctl -p生效;无需重启 Workerman 进程
别碰 tcp_tw_recycle,它在 Workerman 场景下必然出问题
有些老文档会建议同时开启 tcp_tw_recycle 加速回收,但这是危险操作:
- Linux 4.12+ 内核已彻底移除该参数,
sysctl -w net.ipv4.tcp_tw_recycle=1会报错No such file or directory - 即使在旧内核启用,它在 NAT 环境(如 Docker 容器、云厂商 SLB 后)会导致连接随机失败——Workerman 常部署在容器中,极易触发
-
tcp_tw_reuse是它的唯一安全替代,专注客户端侧复用,不涉及时间戳全局递增校验
真正影响 Workerman 连接建立速度的,是端口复用能力与本地端口池大小的组合;单独调小 tcp_fin_timeout 几乎无效,且可能引发 RST 包干扰正常连接。











