本文目录导读:

确定 PHP-FPM 的进程数是 PHP 性能调优中最关键的一步。没有绝对的固定值,而是需要根据服务器的内存、CPU、业务类型和流量动态调整。
以下是一套从公式、参数到具体场景的完整指南:
第一步:核心计算公式
最科学的起点是按内存计算最大进程数。
[ \text{Max_children} = \frac{\text{服务器可用空闲内存}}{\text{单个PHP进程平均内存占用}} ]
- 单个 PHP 进程平均内存:通常通过
ps命令查看(下文有命令)。 - 预留内存:需要给 MySQL、Redis、Nginx 以及系统本身留下足够的缓冲内存,一般建议预留总内存的 20%-30%。
第二步:关键配置参数解析
以 php-fpm.conf(或 www.conf)中的 pm 模式为例:
-
pm = dynamic(推荐大多数生产环境):pm.max_children:最大进程数(最大值不能超过内存限制)。pm.start_servers:启动时的进程数。pm.min_spare_servers:最小空闲进程数(保证有足够进程等待请求)。pm.max_spare_servers:最大空闲进程数(释放多余进程)。
-
pm = static:- 固定
pm.max_children数量,启动后数量不变。 - 适用场景:高并发、低延迟要求,或内存极其充裕的服务器。
- 固定
-
pm = ondemand:- 有请求才启动进程,无请求则销毁。
- 适用场景:低流量、内存特别紧张的小服务器(如 1GB 内存的 VPS)。
第三步:具体操作步骤(实战)
测量单个 PHP-FPM 进程的内存
登录服务器,运行以下命令(Linux):
ps -ylC php-fpm --sort:rss
在输出中,RSS 列(常驻内存集)即为每个进程占用的物理内存(单位 KB)。
假设结果: 平均每个 PHP-FPM 进程占用 50MB,服务器总内存 8GB,需要给系统预留 2GB。
计算适合你的值
- 可用内存 = 8GB - 2GB(预留) = 6GB。
- Max_children = 6144MB(6GB) / 50MB ≈ 122 个进程。
设置配置参数
根据业务并发高低,采取不同的策略:
-
情况 A:并发波动大(推荐 dynamic)
pm = dynamic pm.max_children = 120 ; 上限为计算值 pm.start_servers = 30 ; 启动 1/4 左右 pm.min_spare_servers = 20 pm.max_spare_servers = 50
-
情况 B:并发稳定且极高(推荐 static)
pm = static pm.max_children = 100 ; 直接固定
-
情况 C:1GB 小内存服务器(推荐 ondemand)
pm = ondemand pm.max_children = 20 pm.process_idle_timeout = 10s ; 空闲 10 秒后杀掉进程
第四步:性能检查与动态调整(重要)
设置完成后,不要坐等结果,需要实测并配合监控工具调整。
观察 PHP 错误日志:
查看 /var/log/php-fpm.log 或 /var/log/php7.x-fpm.log(路径因系统而异):
- 如果看到 “WARNING: [pool www] server reached pm.max_children”,说明进程数设置得太少(峰值不够用),需要增加
max_children,但如果此时内存已吃紧,则需考虑优化代码或增加内存。
检查进程队列(健康度指标):
FPM 的日志中通常有一行 max_children 和 max_children_reached。max_children_reached 经常达到上限,说明排队严重,需要加进程或处理请求超时。
使用 top 或 htop 观察:
- CPU 使用率已经 100%,说明瓶颈是 CPU 而不是内存,增加
max_children只会增加排队,应该优化代码或增加 CPU。 - CPU 使用率低于 50%,但内存使用率高达 90% 以上,说明进程数过多,需要减少
max_children。
第五步:避坑指南(常见误区)
- 不要只看 CPU 核心数: PHP-FPM 是网络服务,不是 CPU 计算密集型的
worker,它的数量主要受内存限制,而不是 CPU 核数(2 核机器也可以跑 50 个 PHP 进程,因为 PHP 进程大部分时间在等待数据库响应)。 - 处理长耗时请求(如 API/爬虫): 如果业务中有关键路径耗时较长(如 1 秒以上),并发量会迅速吞掉进程,建议在
php.ini中设置合理的max_execution_time(如 30 秒),并在 Nginx 中设置proxy_read_timeout。 - 避免进程数过多导致内存暴涨: 如果设置过大的
max_children导致内存耗尽,系统会用 Swap(硬盘虚拟内存)来替代,反而导致性能急剧下降(CPU 飙升、响应延迟)。
最简配置策略
| 服务器内存 | 业务模式 | 建议配置 |
|---|---|---|
| 1GB - 2GB | 博客/小网站 | ondemand,max_children = 20 - 30 |
| 4GB - 8GB | 中型业务/API | dynamic,max_children = 50 - 100 |
| 16GB+ | 高并发 | static,max_children = 150 - 200(需配合 CPU) |
最后建议: 配置完成后,使用流量压测工具(如 ab 或 wrk)模拟真实并发,观察响应时间和 nginx error.log 中的超时情况,每次增减 20% 的 max_children,直到找到响应时间和资源占用的最佳平衡点。