PHP-FPM 调优指南:彻底解决网站卡顿、502 / 504 / 500 报错
很多 Laravel / ThinkPHP / WordPress 站点上线后,CPU 飙高、接口超时、随机 502,第一反应往往是“加机器”。但经验表明:80% 的问题来自 PHP-FPM 配置不合理。
本文从原理 → 参数 → 实战 → 排错四个层面,给你一套线上可直接套用的 PHP-FPM 调优方案。
一、先搞懂:PHP-FPM 为什么会卡、会崩?
PHP-FPM 本质是进程池模型:
Nginx → PHP-FPM → Worker 进程 → 执行业务代码当Worker 不够用 / 被占满 / 崩溃 时,就会出现:
现象 | 原因 |
|---|---|
网站变慢 | Worker 被耗尽,请求排队 |
502 Bad Gateway | FPM 挂掉 / socket 不可用 |
504 Gateway Timeout | PHP 执行超时 |
500 Internal Error | 内存不足 / OOM |
👉调优的核心目标:
让 Worker 数量、内存、超时时间与业务负载完全匹配。
二、PHP-FPM 核心配置文件位置
常见路径:
/etc/php/8.2/fpm/php-fpm.conf /etc/php/8.2/fpm/pool.d/www.conf重启命令:
systemctl restart php8.2-fpm三、最重要的 10 个参数(重点)
3.1 pm(进程管理模式)✅
pm = dynamic模式 | 说明 | 推荐 |
|---|---|---|
static | 固定进程数 | ❌ 不推荐 |
dynamic | 动态调整 | ✅ 推荐 |
ondemand | 按需启动 | ❌ 高并发差 |
✅生产环境统一用dynamic
3.2 pm.max_children(最容易配错的参数)
pm.max_children = 50计算公式(非常关键):
max_children ≈ 可用内存 ÷ 单个 PHP 进程平均内存📌 查看单进程内存:
ps -ylC php-fpm --sort:rss示例:
服务器内存:8G
PHP 单进程:60MB
系统预留:2G
(8G - 2G) ÷ 60MB ≈ 100⚠️设置过大 = 内存撑爆 = OOM = 502
3.3 pm.start_servers
pm.start_servers = 20建议值:
pm.start_servers = pm.min_spare_servers + (pm.max_spare_servers - pm.min_spare_servers) / 23.4 pm.min_spare_servers / pm.max_spare_servers
pm.min_spare_servers = 10 pm.max_spare_servers = 30作用:控制空闲进程回收速度,防止频繁 fork。
3.5 pm.max_requests(防内存泄漏)✅
pm.max_requests = 500含义:每个 Worker 处理多少请求后自动重启。
✅ 强烈建议开启,防止:
Laravel 容器膨胀
Redis / PDO 连接未释放
第三方 SDK 内存泄漏
3.6 request_terminate_timeout(解决卡死)
request_terminate_timeout = 30s✅ 防止:
SQL 慢查询
第三方 API 卡死
curl 无限等待
⚠️ 必须大于php.ini中的:
max_execution_time = 253.7 listen 模式选择(非常关键)
✅推荐 TCP(稳定)
listen = 127.0.0.1:9000❌ Unix Socket(高并发易出 502):
listen = /run/php/php8.2-fpm.sock如果必须用 sock,务必设置权限:
listen.owner = www-data listen.group = www-data listen.mode = 06603.8 backlog(高并发必调)
listen.backlog = 1024默认值太小,会导致请求被直接拒绝。
3.9 慢日志(排查卡顿神器)
slowlog = /var/log/php-fpm/slow.log request_slowlog_timeout = 5s✅ 超过 5 秒的请求会被记录,直接定位:
慢 SQL
死循环
阻塞 IO
3.10 错误日志级别
catch_workers_output = yes php_admin_flag[log_errors] = on四、Nginx 配合调优(502 常因这里)
4.1 FastCGI 超时设置
fastcgi_connect_timeout 10; fastcgi_send_timeout 30; fastcgi_read_timeout 30;4.2 Buffer 调整
fastcgi_buffering on; fastcgi_buffer_size 128k; fastcgi_buffers 8 128k;4.3 防止 upstream 错误
proxy_intercept_errors on; fastcgi_intercept_errors on;五、线上推荐配置模板(4C 8G 服务器)
pm = dynamic pm.max_children = 80 pm.start_servers = 20 pm.min_spare_servers = 10 pm.max_spare_servers = 30 pm.max_requests = 500 request_terminate_timeout = 30s listen = 127.0.0.1:9000 listen.backlog = 1024 slowlog = /var/log/php-fpm/slow.log request_slowlog_timeout = 5s catch_workers_output = yes六、如何判断当前 FPM 是否够用?
6.1 查看活跃进程数
ps aux | grep php-fpm | wc -l6.2 查看 Nginx 错误日志
tail -f /var/log/nginx/error.log关键词:
upstream timed outconnection refusedno live upstreams
6.3 查看 PHP-FPM 状态页(强烈推荐)
启用:
pm.status_path = /statusNginx:
location = /status { fastcgi_pass 127.0.0.1:9000; include fastcgi_params; }访问后你会看到:
pool: www process manager: dynamic start time: ... idle processes: 12 active processes: 38 total processes: 50 max active processes: 50✅max active processes 长期接近 max_children → 立刻加进程
七、常见故障排查清单 ✅
502 Bad Gateway
[ ] PHP-FPM 是否存活
[ ] listen 地址是否一致
[ ] socket 权限是否正确
[ ] backlog 是否过小
[ ] max_children 是否耗尽
504 Gateway Timeout
[ ] request_terminate_timeout 是否太短
[ ] SQL 慢查询
[ ] 第三方 API 阻塞
[ ] curl 未设 timeout
网站间歇性卡顿
[ ] 未设置 pm.max_requests
[ ] Redis / MySQL 连接未释放
[ ] Laravel 容器内存膨胀
[ ] Opcache 未开启
八、Laravel 项目特别注意事项
✅ Opcache 必须开启
✅config:cache、route:cache
✅ 禁用DB::listen在生产环境
✅ 队列 worker 单独进程,不要混用 FPM
✅ 不要在 FPM 里跑长任务(导出 / 同步)
九、一句话总结
PHP-FPM 调优的本质:
不让进程饿死(太少)
不让内存炸裂(太多)
不让请求卡死(超时)
不让错误隐形(日志)