PHP不参与WebSocket负载均衡,实际由Nginx反向代理实现;需配置proxy_http_version 1.1、Upgrade和Connection头,并用ip_hash保证连接粘性;PHP应使用Swoole或Workerman作为服务端,避免Apache/FPM。

PHP 客户端连 WebSocket 时,负载均衡根本不在 PHP 侧做
PHP 本身没有原生 WebSocket 客户端(fsockopen 或 stream_socket_client 可以手动实现,但不推荐),更不会参与 WebSocket 连接的负载分发。所谓“PHP 连 WebSocket 负载均衡”,实际是:PHP 后端作为「服务提供方」被前端 WebSocket 客户端连接,或 PHP 作为「中转代理」把请求转发给后端 WebSocket 服务集群——负载均衡发生在反向代理层,不是 PHP 代码里配出来的。
Nginx 代理 WebSocket 需显式开启 upgrade 协议支持
WebSocket 握手依赖 HTTP Upgrade 机制,Nginx 默认不透传 Connection 和 Upgrade 头,直接反代会返回 400 或连接立即断开。
必须在 location 块中补全以下配置:
location /ws/ {
proxy_pass http://ws_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
-
proxy_http_version 1.1是强制项,HTTP/1.0 不支持 Upgrade -
$http_upgrade是 Nginx 内置变量,大小写敏感,不能写成$http_UpgrAde - 如果后端是多个节点,
upstream ws_backend需用ip_hash或hash $remote_addr consistent,避免同一客户端反复重连(WebSocket 连接有状态)
PHP 作为 WebSocket 服务端时,别用 Apache,选 Swoole 或 Workerman
Apache 和传统 PHP-FPM 架构无法长期维持 WebSocket 连接,每个请求都是无状态短连接。真要跑 WebSocket 服务,得用常驻内存的 PHP 框架:
立即学习“PHP免费学习笔记(深入)”;
-
Swoole\WebSocket\Server支持多进程 + 端口复用,配合nginx -> swoole反代即可横向扩展 -
Workerman更轻量,启动多个 worker 进程后,靠系统负载均衡(如systemd的StartLimitIntervalSec控制重启)或外部进程管理器调度 - 两者都不自带跨机器 session 共享,客户端重连到不同节点时,需用 Redis 存储连接映射(
fd → user_id)和广播状态
前端 JS 连接时,负载均衡失效的常见信号
浏览器控制台看到 WebSocket connection to 'wss://...' failed: Error during WebSocket handshake,大概率是反代没透传 Upgrade;如果连接成功但消息收发错乱、频繁掉线,可能是:
- 没启用
ip_hash,导致同个用户被轮询到不同后端节点,而节点间未同步连接状态 - SSL 终结在 Nginx,但后端 WebSocket 服务误配为
wss协议(应配ws),或证书路径未正确透传 - 防火墙/安全组只放行了某台机器的端口,其他节点实际不可达
- 健康检查没配(
health_check interval=3 fails=2),挂掉的节点还在转发流量
负载均衡不是加个 upstream 就完事,关键在连接粘性、状态同步和链路可观测性——这些环节漏掉一个,PHP 写得再好也扛不住连接抖动。











