## 背景与目标

在高并发场景下,PHP-FPM 与 Nginx 的容量需协同设计。本文通过可验证的方法计算 `pm.max_children`,并给出压测流程与观测指标,避免盲目调参导致抖动与 OOM。


## 关键参数与可计算公式

  • `pm`:`static` 或 `dynamic`(生产常用 `dynamic`)
  • `pm.max_children`:并发可同时处理的 PHP 请求数(与可用内存严格相关)
  • 可计算公式(预留安全冗余):
  • `pm.max_children ≈ floor((RAM_for_PHP * 0.75) / avg_child_RSS)`
  • 其中 `RAM_for_PHP` 为留给 PHP-FPM 的可用内存,`avg_child_RSS` 为单个子进程的常态驻留内存(RSS)。
  • `pm.start_servers`、`pm.min_spare_servers`、`pm.max_spare_servers`:仅在 `dynamic` 下生效,用于控制空闲子进程池规模。

## 测量 PHP-FPM 子进程内存(RSS)

1. 在目标业务路由上进行预热(避免冷启动偏差)。

2. 使用 `ps`/`smem` 观测 RSS(示例为常见 Linux 环境):

   # 查看 php-fpm 进程及常见 RSS 范围
   ps -o pid,cmd,rss --sort=-rss | grep php-fpm
   # 更精确可用 smem(需安装)
   smem -P php-fpm

3. 计算 `avg_child_RSS`:剔除异常值后取平均(建议以业务高峰时段测值为准)。


## 计算示例

  • 服务器可用内存(给 PHP)`RAM_for_PHP = 8 GiB`
  • 观测 `avg_child_RSS ≈ 90 MiB`
  • 预留 25% 安全冗余:`pm.max_children ≈ floor((8 * 1024 * 0.75) / 90) ≈ 68`

> 将 `pm.max_children` 设为 60–68,并在压测与生产观测中微调。


## Nginx 并发容量与连接限制

  • `worker_processes auto;`:跟随 CPU 核心数。
  • `worker_connections`:单 worker 可同时打开的连接数。
  • 近似上限:`max_clients ≈ worker_processes * worker_connections`
  • 实际受 `ulimit -n`(最大文件句柄)、上游连接、Keep-Alive 等影响。
  • 示例配置:
  •   worker_processes auto;
      events {
          worker_connections 4096;
          # use epoll;  # Linux 下可启用,根据平台选择
      }
      http {
          sendfile on;
          keepalive_timeout 65;
          upstream php_backend {
              server 127.0.0.1:9000 max_fails=3 fail_timeout=30s;
          }
          server {
              listen 80;
              location ~ \.php$ {
                  include fastcgi_params;
                  fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                  fastcgi_pass 127.0.0.1:9000;
              }
          }
      }
    

## 压测流程(可复现)

1. 工具选择:`wrk` 或 `ab`(推荐 `wrk`)。

2. 场景设计:

  • QPS 拉升阶梯:如 `-c 200/400/800`,`-t` 取 CPU 线程数。
  • 持续时间:不少于 30s,避免瞬时波动。

3. 命令示例:

   wrk -t8 -c400 -d60s http://your-host/index.php
   ab -n 20000 -c 400 http://your-host/index.php

4. 观测指标:

  • Nginx:`active connections`、`5xx` 比例、`upstream_connect_time`(如启用日志)。
  • PHP-FPM:`slowlog`、`status` 页(`/status`)、`max children reached` 告警。
  • 系统:`loadavg`、`CPU iowait`、`RSS` 变化、`dmesg` 是否有 OOM。

## 常见问题与定位

  • `max children reached`:提高 `pm.max_children` 或优化业务使单次请求更快、占用更少内存。
  • 5xx 抖动:检查上游超时、`fastcgi_read_timeout`、网络队头阻塞。
  • OOM:为 PHP-FPM 分配的内存不足或 `avg_child_RSS` 估计过低。

## 配置示例(PHP-FPM)

[www]
pm = dynamic
pm.max_children = 64
pm.start_servers = 8
pm.min_spare_servers = 8
pm.max_spare_servers = 16
pm.max_requests = 1000
request_terminate_timeout = 60s
listen = 127.0.0.1:9000

## 验证清单(落地可检查项)

  • 已在业务高峰期重新测量 `avg_child_RSS`,并更新计算结果。
  • `pm.max_children` 调整后进行 30–60 分钟压测与观测,无 OOM、5xx 无异常抖动。
  • Nginx `worker_connections` 与系统 `ulimit -n` 协调一致。
  • 记录变更与观测数据,形成容量基线与告警阈值。

## 总结

通过可复现的测量与计算,`pm.max_children` 与 Nginx 并发容量能够稳定协同,避免资源瓶颈与故障放大,最大化吞吐同时保障稳定性。



点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部