news 2026/10/21 2:40:20

PHP-FPM调优实战:QPS从800飙至2400

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PHP-FPM调优实战:QPS从800飙至2400

一、写在前面:网站为什么突然变慢了

前阵子接手一个老项目,用的是典型的 LNMP 架构。业务量其实不算大,但一到下午高峰期,用户就开始反馈页面转圈、接口超时。一开始怀疑是数据库慢查询,排查了一圈发现 SQL 都挺正常,后来把目光放到 PHP-FPM 上,才发现问题比想象中严重得多。

这篇文章不聊太虚的理论,就讲讲我实际踩过的坑,以及最后是怎么通过调整 PHP-FPM 参数,把 QPS 从原来的 800 左右拉到 2400 多的。整个过程大概花了一个下午,收益却非常明显。

二、先搞清楚 PHP-FPM 到底在忙什么

简单说,PHP-FPM 就是 PHP 的进程管理器,它负责维护一批 worker 进程,等待请求进来后分配处理。每个请求都会占用一个 worker,处理完才释放。所以 worker 数量、超时时间、进程回收策略,直接决定了网站的并发处理能力。

我当时用ps aux | grep php-fpm看了一眼,发现默认配置下开了 128 个 worker,但实际活跃的只有十几个,其余全在空转。这其实是个很典型的信号:进程开得多不代表性能好,反而会白白吃掉内存。

三、调优前先做一次体检

动手之前,我习惯先收集几组数据,不然改参数就是瞎猜。主要看三个东西:

  • 当前 QPS 和响应时间:用 ab 或者 wrk 压一下,记录基线数据。
  • PHP-FPM 状态页:开启pm.status_path,能看到 active、idle、max_children 等实时指标。
  • 内存占用:每个 worker 平均吃多少内存,决定能开多少个进程。

下面是我当时用的压测命令,简单粗暴但够用:

# 先压 30 秒,看看基线 wrk -t4 -c100 -d30s http://your-site.com/api/test 顺便看下 PHP-FPM 状态页 curl http://your-site.com/phpfpm_status?full

压完一看,QPS 稳定在 800 上下,平均延迟 120ms,p99 已经飙到 400ms 了。这个数据说实话不太好看,但也给了我们明确的优化方向。

四、核心参数怎么调

PHP-FPM 的调优,说白了就是围绕pm、pm.max_children、pm.start_servers、pm.min_spare_servers、pm.max_spare_servers这几个参数做文章。我踩过的坑主要有两个:一是进程开太多导致内存吃紧,二是超时时间设置不合理导致请求堆积。

1. 进程管理方式:动态比静态更省心

默认的pm=dynamic其实挺合理,它会根据空闲进程数自动调整 worker 数量。但很多人图省事直接改成pm=static,结果高峰期不够用,低峰期又浪费内存。我建议保持 dynamic,重点调好上下限。

2. max_children 不是越大越好

这个参数决定最多能同时开多少个 worker。开太多,内存扛不住;开太少,高峰期直接排队。我当时按「总内存 / 单进程内存」来估算,比如服务器 16G 内存,每个 worker 平均占 80M,那上限大概 160 左右,留点余量就设 128。

配置大概长这样:

pm = dynamic pm.max_children = 128 pm.start_servers = 32 pm.min_spare_servers = 16 pm.max_spare_servers = 64 pm.max_requests = 500

3. max_requests 一定要设

这个参数很多人会忽略,但它其实很重要。它控制 worker 处理多少个请求后自动重启,能有效防止内存泄漏累积。我设的 500,跑了一段时间观察,内存曲线平稳多了。

4. 超时时间别乱调

request_terminate_timeout默认 0 表示不限制,但实际生产环境建议设个值,比如 30 秒。不然某个慢请求会一直占着 worker 不放,拖垮整个进程池。我当时就遇到过一个第三方接口响应特别慢,把 worker 全占满了,设了超时后立刻缓解。

五、改完之后的对比

参数改完,重启 PHP-FPM,再跑一遍同样的压测:

# 重启服务 systemctl reload php-fpm 重新压测 wrk -t4 -c100 -d30s http://your-site.com/api/test

结果 QPS 从 800 涨到了 2400 多,平均延迟降到 40ms,p99 也压到了 120ms 以内。说实话这个提升幅度我自己都有点意外,但仔细想想也合理:之前进程分配不合理,大量请求在排队,现在 worker 数量和回收策略都对了,吞吐自然就上来了。

六、几点补充建议

调优不是一锤子买卖,上线后还得持续观察。我建议把 PHP-FPM 状态页接入监控,比如用 Prometheus 定期抓取,配合告警规则,一旦 active 进程数接近 max_children 就提醒。另外,如果业务量继续涨,光调 PHP-FPM 是不够的,还得考虑加缓存、上负载均衡,甚至拆分服务。

最后提醒一句:每个项目的硬件配置、业务特点都不一样,别直接抄我的参数。先压测拿基线,再小步调整,每次只改一两个参数,观察效果后再动下一个。这样既稳妥,出了问题也容易回退。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/21 2:37:31

高等数学1

无穷序列 在高中时期我们就学习了一些数列的内容。数列可以由 能有限项推出规律的({1,3,5,71 ,3 ,5 ,71,3,5,7}公差为1);具有通项公式的(an3n−2a_n3n-2an​3n−2);通过递推公式(an2an−1−1a_n2a_{n-1}-1a…

作者头像 李华
网站建设 2026/10/21 2:37:06

〖实战〗物流车辆实时调度与路线最优规划:Redis GEO 召回、OR-Tools 求解与 Oracle 空间数据的 Java/Spring Boot 工程实现

一、痛点场景:调度员盯着地图点鼠标,系统只在“存数据”物流车辆调度系统有一个常见的“假自动化”陷阱:系统里有车辆位置、有订单地址、有地图,调度员却仍然要手动把订单拖给某辆车。系统做的是“记录调度结果”,而不…

作者头像 李华