温馨提示×

Linux PHP-FPM如何进行负载均衡

小樊
39
2025-12-24 03:37:53
栏目: 云计算

Linux PHP-FPM负载均衡实战指南

一、架构选型与总体思路

  • 常见做法是在 Nginx 与 PHP-FPM 之间或前置 HAProxy 做负载均衡。PHP-FPM 本身不提供跨进程/跨机器的调度,需要由上游反向代理或负载均衡器分发 FastCGI 请求。
  • 典型拓扑:
    • 单机多实例:一台机器运行多个 PHP-FPM pool/实例(不同端口或不同 Unix socket),由 Nginx upstream 分发,适合容量扩展与资源隔离。
    • 多机集群:多台应用服务器各运行 PHP-FPM,由 NginxHAProxy 统一接入与分发,适合横向扩容和高可用。

二、方案一 Nginx upstream 直接负载均衡到多个 PHP-FPM

  • 适用:单机多实例或多机集群,配置简单、维护成本低。
  • 关键配置示例(/etc/nginx/nginx.conf 或 /etc/nginx/conf.d/php-upstream.conf):
http {
  upstream php_backend {
    # 方式A:Unix socket(同机多实例)
    server unix:/run/php/php7.4-fpm-1.sock;
    server unix:/run/php/php7.4-fpm-2.sock;

    # 方式B:TCP 端口(跨机或同机多实例)
    # server 10.0.0.11:9000 weight=1 max_fails=3 fail_timeout=30s;
    # server 10.0.0.12:9000 weight=1 max_fails=3 fail_timeout=30s;

    # 负载均衡策略(按需选择其一)
    # least_conn;   # 最少连接
    # ip_hash;      # 会话保持(基于客户端IP)
    # 默认轮询
  }

  server {
    listen 80;
    server_name example.com;
    root /var/www/html;
    index index.php index.html;

    location / {
      try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
      include fastcgi_params;
      fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
      fastcgi_index index.php;
      fastcgi_pass php_backend;   # 指向 upstream 名称
    }
  }
}
  • 要点:
    • 使用 Unix socket 时,需确保 Nginx worker 进程用户与 PHP-FPM 的 listen.owner/listen.group 一致,且 socket 文件可被访问。
    • 使用 TCP 时,PHP-FPM 需监听 0.0.0.0:9000 或指定网卡 IP,并配置 listen.allowed_clients 限制来源(如只允许前端 Nginx/HAProxy 网段)。

三、方案二 HAProxy 作为前端负载均衡器

  • 适用:更复杂的调度、健康检查、权重与灰度等能力。
  • 关键配置示例(/etc/haproxy/haproxy.cfg):
global
  log /dev/log local0
  log /dev/log local1 notice
  daemon

defaults
  log global
  mode http
  option httplog
  option dontlognull
  timeout connect 5000ms
  timeout client  50000ms
  timeout server  50000ms

frontend http_front
  bind *:80
  default_backend php_back

backend php_back
  balance roundrobin
  # Unix socket 示例(需 HAProxy 支持 Unix socket,部分版本/编译选项支持)
  # server php1 unix@/run/php/php7.4-fpm-1.sock check
  # server php2 unix@/run/php/php7.4-fpm-2.sock check

  # TCP 示例(更通用)
  server php1 10.0.0.11:9000 check
  server php2 10.0.0.12:9000 check
  • 要点:
    • 若使用 Unix socket,需确认 HAProxy 编译时启用 USE_UNIX_SOCKET;否则建议用 TCP 端口方式。
    • 可结合 ACL/权重/健康检查 实现灰度与故障隔离。

四、方案三 单机多实例 PHP-FPM 配置要点

  • 复制并调整多个 pool 配置(/etc/php/7.4/fpm/pool.d/):
; www1.conf
[www1]
user = www-data
group = www-data
listen = /run/php/php7.4-fpm-1.sock
listen.owner = www-data
listen.group = www-data
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 10

; www2.conf
[www2]
user = www-data
group = www-data
listen = /run/php/php7.4-fpm-2.sock
listen.owner = www-data
listen.group = www-data
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 10
  • 启动多个实例(以 systemd 为例,可按需写单元或启动脚本):
# 复制服务或自定义单元后,分别启动
systemctl start php7.4-fpm@www1
systemctl start php7.4-fpm@www2
# 或指定配置文件启动
php-fpm -y /etc/php/7.4/fpm/pool.d/www1.conf
php-fpm -y /etc/php/7.4/fpm/pool.d/www2.conf
  • 在 Nginx 的 upstream 中列出多个 socket/端口 即可完成分发。

五、验证、调优与排错

  • 验证与观测
    • 语法与连通性:
      • Nginx:nginx -t
      • HAProxy:haproxy -c -f /etc/haproxy/haproxy.cfg
    • 查看监听与进程:ss -lntp | grep php-fpm;ps -ef | grep php-fpm
    • 简单测试脚本(确认分发与一致性):
      <?php
      header('Content-Type: text/plain');
      echo "Host: " . gethostname() . "\n";
      echo "Remote: " . $_SERVER['REMOTE_ADDR'] . "\n";
      echo "Time: " . date('Y-m-d H:i:s') . "\n";
      
  • 调优建议
    • 进程与内存:根据 内存/并发 调整 pm.max_children/start_servers/min_spare_servers/max_spare_servers;经验上每个 FPM 进程约 5–15MB,据此估算总进程数与 pm.max_children
    • 连接与健康检查:合理设置 max_fails/fail_timeout,启用 主动健康检查(HAProxy)或 fastcgi_next_upstream(Nginx)提升容错。
    • 传输方式:同机优先 Unix socket(更低开销),跨机使用 TCP 9000,并限制 listen.allowed_clients
    • 会话亲和:如需会话保持,Nginx 可用 ip_hash,或在应用侧使用 Redis 等集中会话存储

0