单机正常并发就504?PHP-FPM进程数调优指南
最近, 有几个身为站长的朋友, 碰到了同一个极难解决的问题, 网站只要有单独一人进行访问, 所有情况毫无异常, 可要是一旦遭遇并发访问, 便会频繁地冒出504 Gateway Timeout这种状况。这样一种“单独行动时所向披靡, 多人齐上就会崩溃”的典型现象, 很大程度上是后端应用服务器的处理能力存在欠缺, 在PHP站点里这种情况最为常见, 其根源常常是出在PHP - FPM进程池的配置情况上。
一、504 超时的根本原因
五百零四意味着网关出现超时状况。你所使用的 Nginx 将请求转交给了 PHP-FPM, 然而 PHP-FPM 处于忙碌状态无法应对, 或者单个请求执行需要耗费过长时间, 以至于 Nginx 等不到结果就断开了连接。当单人进行访问时, PHP-FPM 进程处于空闲状态, 自然不会出现超时情况;随着并发量上升之后,所有子进程都被占据满了, 新的请求只能排队等着, 直至 Nginx 的 fastcgi_read_timeout 时间一到就会报错。
二、核心调优参数(直接可操作)
于你的php-fpm.conf或者与之对应的pool配置文件(像是www.conf)进行编辑, 着重将以下三个参数予以调整。
| 参数 | 作用 | 建议值(根据内存调整) |
|---|---|---|
pm.max_children | 最大子进程数 | 内存总量(GB)× 40 |
pm.start_servers | 启动时的进程数 | 建议设为 max_children 的 25% |
pm.max_spare_servers | 最大空闲进程数 | 等于 max_children 或略低 |
示例配置(2GB 内存服务器):
pm = dynamic pm.max_children = 80 pm.start_servers = 20 pm.min_spare_servers = 10 pm.max_spare_servers = 40
要同时去检查, Nginx 的 fastcgi_read_timeout 是不是过短, 建议把它设置为 60s 或者更长一些:
fastcgi_read_timeout 60;
三、进一步排查
如果调整后问题依旧,请检查:
执行慢查询日志, 开启了 request_slowlog_timeout 等于 5 秒的时长设定,从而寻得了脚本方面存在的瓶颈之处。
针对数据库连接池, PHP - FPM 的每个进程都会维持各自独立的数据库连接, 要是并发量高的话, 就有可能致使数据库连接数达到爆满状态, 这种情况下, 可以改用 pdo 持久连接或者增加 max_connections 的数值, 以此应对。
四、建议配合的架构优化
针对那些具备条件的站长来讲, 建议把静态资源(诸如图片、CSS、JS 这些)交付给 CDN 或者独立静态服务器, 以此降低 PHP 进程所承载的负载。与此同时, 要思量运用 OPcache 去加速 PHP 执行, 用以削减每次请求时产生的编译开销。
多个实际站点里, 皆验证了上述方法是有效的, 要是碰到复杂场景, 不妨亲自去测试调优, 然后观察日志。
否玩代码编辑 https://www.fouwan.com


