## 背景与目标
在高并发场景下,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 并发容量能够稳定协同,避免资源瓶颈与故障放大,最大化吞吐同时保障稳定性。

发表评论 取消回复