应选用云厂商nlb而非alb或clb,因nlb原生支持tcp/udp、健康检查默认tcp握手,天然适配workerman长连接;alb不支持纯tcp,clb默认http探活易误判;配置需设监听及后端协议为tcp、关闭ip hash、健康检查切为tcp并填正确端口;workerman须监听0.0.0.0且放行端口;注意proxy protocol v2才能获取真实客户端ip。

直接用云厂商的 NLB(网络型负载均衡)即可,Workerman 本身不暴露 HTTP 协议,四层 TCP 转发最匹配、最省事,也最稳定。
为什么必须选 NLB 而不是 ALB 或 CLB?
ALB 是七层负载均衡,只支持 HTTP/HTTPS/QUIC,tcp://0.0.0.0:2345 这类纯 TCP 服务它根本无法识别和转发;CLB 虽然支持 TCP,但它的健康检查默认走 HTTP 探针,对 Workerman 的 TCP 长连接服务容易误判为“不可用”——除非你额外配 TCP 端口探活,但配置路径绕、文档藏得深。NLB 原生就是为 TCP/UDP 设计的,健康检查默认走 TCP 握手(SYN 包),天然适配 Workerman 的连接模型。
关键点:
- NLB 的监听协议必须选
TCP,不能选TCPSSL(除非你真在 Workerman 侧做了 TLS 终结,但绝大多数场景不需要) - 后端服务器组的协议必须设为
TCP,且关闭“客户端地址保持”(即 IP Hash),否则长连接会粘死在单台机器上,失去负载意义 - 阿里云 NLB 控制台里,“健康检查”页签下务必把检查方式从
HTTP切换为TCP,并填入 Workerman 实际监听的端口(如2345)
Workerman 后端节点要怎么准备?
Workerman 不需要任何特殊改造,只要确保它监听的是 0.0.0.0:2345(而非 127.0.0.1:2345),且防火墙放行该端口即可。NLB 的健康检查包是从云内网发出的,目标是你的 ECS 内网 IP + 端口,所以不要配错监听地址。
常见错误现象:
- NLB 控制台显示“后端服务器异常”,但 telnet 自己能通 → 很可能是 Workerman 监听了
127.0.0.1,导致 NLB 探活失败 - 连接建立后立刻断开 → 检查 Workerman 的
$worker->onClose是否有未捕获异常,或是否在onMessage中用了阻塞操作(如 file_get_contents 同步调用)导致事件循环卡住 - 部分连接收不到数据 → 确认 NLB 的“空闲连接超时”设置(默认 4000 秒),若 Workerman 有心跳机制,需保证间隔小于该值,否则连接被 NLB 主动中断
如何验证 NLB 是否真正生效?
别只看控制台状态绿灯,要实测流量分发效果:
- 在每台 Workerman 后端加一行日志:
echo "Received from " . $connection->getRemoteIp() . " via NLB\n";,然后用多个客户端(不同公网 IP)连 NLB 的 VIP,观察日志是否轮询出现在不同机器上 - 用
ss -tnp | grep :2345查看每台 ECS 上的 ESTAB 连接数,正常应大致均衡(允许小偏差) - 故意停掉一台 ECS,观察 NLB 是否在 30 秒内(默认健康检查间隔 × 3 次失败)停止转发,并确认剩余机器连接数上升
注意:NLB 不透传客户端真实 IP,默认看到的是 NLB 的内网 IP。如需获取真实 IP,必须开启“Proxy Protocol v2”并在 Workerman 中解析($connection->getRemoteIp() 不再可用,得从连接头里手动读取)——这一步容易漏,而且 Workerman 默认不支持 PPv2,需自行解析或改用支持 PPv2 的封装库。











