PHP本身不处理负载均衡,必须靠反向代理(如Nginx或HAProxy)在前端分发请求;PHP应用需无状态部署并统一用Redis存储Session,Nginx upstream须配置max_fails、fail_timeout及健康检查,同时proxy_set_header必须传递Host、X-Real-IP和X-Forwarded-For,且后端PHP服务须监听非localhost网络接口。

Nginx 或 HAProxy)在前端做请求分发;PHP应用只需无状态部署、共享 Session 存储,剩下的交给反向代理配置。
为什么不能用 PHP 自己做负载均衡
PHP 是单进程、阻塞式脚本语言,file_get_contents 或 cURL 转发请求会严重拖慢响应、阻塞 worker、无法健康检查,且无法维持长连接或复用连接。实际生产中没人用 PHP 写反向代理层——它不是干这个的。
Nginx upstream 必须配的三项参数
仅写 upstream 块但没加健康探测,等于裸奔:某台 PHP 服务器挂了,Nginx 还继续往里扔请求,用户就看到 502。
-
max_fails=3:连续失败 3 次才标记为不可用 -
fail_timeout=30s:30 秒内不把请求发给这台机器(注意不是“30 秒后自动恢复”,而是从最后一次失败起算) -
health_check interval=3 fails=2 passes=2(需启用ngx_http_upstream_health_check_module,OpenResty 自带;官方 Nginx 需编译时加模块):主动 HTTP 探针,比被动失败更早发现 PHP-FPM 卡死
Session 不一致?别存文件,改用 redis
默认 session.save_handler = files 会导致用户登录后刷新跳到另一台服务器,立刻登出。这不是负载均衡的问题,是 Session 存储没统一。
- 确认 PHP 已启用
redis扩展:php -m | grep redis - 修改
php.ini:session.save_handler = redis session.save_path = "tcp://127.0.0.1:6379?database=0" session.cookie_httponly = 1
- 确保所有 PHP 服务器连的是同一个 Redis 实例(或集群),且
redis实例本身高可用(主从 + Sentinel 或 Redis Cluster)
proxy_set_header 漏掉这三项,PHP 就拿不到真实客户端信息
很多配置只写 proxy_pass,忘了传关键头,结果 $_SERVER['REMOTE_ADDR'] 全是 127.0.0.1,日志和限流全乱。
立即学习“PHP免费学习笔记(深入)”;
-
proxy_set_header Host $host;:保持原始 Host,避免 Laravel 或 ThinkPHP 的 URL 生成出错 -
proxy_set_header X-Real-IP $remote_addr;:让 PHP 能读到真实 IP($_SERVER['HTTP_X_REAL_IP']) -
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;:链路中可能有多层代理时补全 IP 链
fastcgi_pass 地址(如果是 PHP-FPM)或 proxy_pass 地址(如果是 Swoole/Workerman),必须监听在 非 localhost 的网络接口(比如 0.0.0.0:9000),否则其他机器根本连不上。本地回环地址只对本机有效。



















