内网压测跑满万兆而公网仅几百兆,根本原因不在Workerman,而是公网链路中NAT、防火墙、运营商限速、TCP窗口缩窄或HTTPS加解密等上游瓶颈所致。

内网压测跑满万兆,但公网只有几百兆——根本不是带宽问题
Workerman 在内网压测能打满万兆网卡,说明它的 IO 能力、event 扩展、连接数配置都没问题;公网只跑几百兆,99% 的情况和 Workerman 本身无关,而是被上游链路或协议层卡死了。别急着调 Worker::$maxConnection 或重编译 PHP,先看真实瓶颈在哪。
公网流量被 NAT / 防火墙 / 运营商限速截断
内网直连无中间设备,TCP 握手快、RTT 低、窗口开得足;公网请求必经光猫 → 家用路由器(NAT)→ 运营商城域网 → 骨干网 → 你的服务器。任一环节丢包、延迟高、连接数限制或策略限速,都会让 TCP 吞吐暴跌。
- 家用路由器的 NAT 并发连接数普遍卡在 2000–8000,远低于 Workerman 的
$maxConnection,大量连接在 SYN_SENT 或 TIME_WAIT 状态堆积 - 光猫或运营商 OLT 设备对单 IP 新建连接速率(connection per second)做限制,压测时触发限速,表现为“连接建立慢”或“大量超时”
- 部分地区宽带套餐标称“千兆”,但上行实际仅 30–50Mbps,而压测工具(如 wrk、ab)默认并发高、请求密集,上行打满后下行也同步恶化
客户端与服务端 TCP 参数不匹配,窗口缩到百兆级
内网环境双方 MTU 一致、RTT ≈ 0.1ms,TCP 自动协商出大窗口(64KB+);公网 RTT 常达 20–60ms,若服务端未启用 tcp_window_scaling 或客户端窗口通告太小,有效吞吐直接掉到 窗口大小 / RTT 量级——算下来就是几百 Mbps。
- 检查服务端:
sysctl net.ipv4.tcp_window_scaling必须为 1;net.core.rmem_max和wmem_max建议 ≥ 4194304(4MB) - 压测客户端(如 Linux 机器)也要确认:
echo 'net.core.rmem_max = 4194304' >> /etc/sysctl.conf,否则接收窗口卡死在 64KB - 用
ss -i抓一个公网连接,看wscale是否生效、cwnd(拥塞窗口)是否长期 ≤ 10
HTTPS 加解密拖垮吞吐,且未启用 TLS 1.3 + 零拷贝
内网压测常走 HTTP 明文,绕过 TLS 开销;公网生产环境强制 HTTPS,OpenSSL 软件加解密在高并发下极易成为 CPU 瓶颈,尤其当 Workerman 进程数少、又没开异步 SSL 时。
- 确认是否用了
Swoole\Http\Server替代 Workerman 做 HTTPS?Workerman 原生不支持异步 TLS,靠stream_socket_enable_crypto是同步阻塞的 - 必须启用 TLS 1.3(降低握手往返)、禁用老旧 cipher suite(如
openssl ciphers -V 'DEFAULT@SECLEVEL=2' | grep -E 'TLS1.3|CHACHA') - 硬件加速可选:Intel QAT 或 OpenSSL engine 支持 AES-NI,但需重新编译 PHP + OpenSSL,普通部署慎入
最常被忽略的一点:压测工具本身跑在 NAT 后或带宽受限的 VPS 上,它发不出足够流量,就别怪 Workerman 没吃饱。先用 iperf3 -c your_server_ip -P 32 直测 TCP 吞吐,再谈应用层优化。

















