在 Nginx 中实现对后端多台机器 PHP-FPM 的负载均衡,主要有 两种架构方案。你需要根据你的实际部署情况选择:
方案一:Nginx 直接负载均衡 PHP-FPM(FastCGI 层面)
这种方案下,Nginx 作为统一的入口,直接将 PHP 请求通过 FastCGI 协议分发到不同服务器的 PHP-FPM 进程上。
1. Nginx 负载均衡配置在 Nginx 的 http 块中定义 upstream,然后在 server 中调用。
http {
# 定义 PHP-FPM 后端集群
upstream php_fpm_cluster {
# server 后面是后端机器的 IP 和 PHP-FPM 监听端口
server 192.168.1.101:9000 weight=1;
server 192.168.1.102:9000 weight=1;
server 192.168.1.103:9000 weight=1;
# 可选:故障转移配置
# 30秒内失败3次,则30秒内不再转发给该机器
# server 192.168.1.101:9000 max_fails=3 fail_timeout=30s;
}
server {
listen 80;
server_name example.com;
# ⚠️ 注意:这个路径必须和所有后端机器上的代码路径完全一致
root /var/www/html;
location ~ \.php$ {
include fastcgi_params;
# 关键:指向 upstream 名称,而不是具体的 IP
fastcgi_pass php_fpm_cluster;
# 传递脚本绝对路径给后端 PHP-FPM
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
} 2. 后端 PHP-FPM 配置修改默认情况下,PHP-FPM 只监听本地 Socket 或 127.0.0.1:9000。要允许 Nginx 跨机器访问,必须修改每台后端机器的 PHP-FPM 配置(通常在 /etc/php/7.4/fpm/pool.d/www.conf 或 /etc/php-fpm.d/www.conf):
; 修改 listen 为内网 IP 或 0.0.0.0 listen = 192.168.1.101:9000 ; 允许连接的客户端 IP(只允许 Nginx 负载均衡器的 IP 访问,保障安全) listen.allowed_clients = 192.168.1.100
修改后重启 PHP-FPM:systemctl restart php-fpm 或 systemctl restart php7.4-fpm。
方案一的致命前提:代码必须一致因为 Nginx 会随机把请求发给 101 或 102,如果 101 上有 index.php 而 102 上没有,用户就会间歇性看到 404 或旧代码。
解决办法:所有后端机器必须挂载共享存储(如 NFS、GlusterFS、阿里云 NAS),或者通过发布系统严格保证代码实时同步。
方案二:Nginx 负载均衡完整的 Web 节点(HTTP 层面)—— 【生产环境更推荐】
这是更标准、更易维护的做法。Nginx 负载均衡器只负责分发 HTTP 请求,后端每台机器自己跑一个 Nginx(或 Apache)+ PHP-FPM。
1. Nginx 负载均衡配置http {
upstream web_cluster {
server 192.168.1.101:80;
server 192.168.1.102:80;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://web_cluster;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
} 2. 后端机器配置每台后端机器(101, 102)上正常配置 Nginx 连接本地的 PHP-FPM(推荐使用 Unix Socket,性能更好且无需开放端口)。
优势:后端可以独立扩展,代码部署更灵活,排查问题更容易,且后端 Nginx 可以处理静态文件缓存。
进阶配置技巧
1. 负载均衡策略在 upstream 中,你可以配置不同的分发策略:
| 轮询(默认) | 不写 | 按顺序依次分发 |
| 权重 | server 192.168.1.101:9000 weight=3; | 性能好的机器多分配请求 |
| IP Hash | ip_hash; | 同一客户端 IP 固定访问同一台机器(解决本地 Session 问题) |
| 最少连接 | least_conn; | 优先分发给当前连接数最少的机器 |
Nginx 开源版自带被动健康检查:
upstream php_fpm_cluster {
server 192.168.1.101:9000 max_fails=3 fail_timeout=30s;
server 192.168.1.102:9000 max_fails=3 fail_timeout=30s;
} 含义:如果 30 秒内某台机器连接失败 3 次,Nginx 会把它标记为不可用,接下来的 30 秒内不再转发请求给它。
3. 安全建议不要暴露 9000 端口到公网:PHP-FPM 没有身份验证机制,公网暴露 9000 端口极易被攻击者利用执行任意代码。
防火墙限制:后端机器的 9000 端口只允许 Nginx 负载均衡器的内网 IP 访问。
内网通信:Nginx 和 PHP-FPM 之间尽量走内网,延迟低且安全。
Session 处理:如果使用了 ip_hash 或本地文件存 Session,建议改为 Redis 集中存储 Session,否则机器宕机会导致用户登录态丢失。
网友回复


