Home 建站 LNMP LNMP | php-fp...

LNMP | php-fpm.conf 优化与容量规划(static / dynamic 调优实战)

0

适用环境:军哥 LNMP(/usr/local/php/)、Nginx + PHP-FPM + MySQL。
目标:让 PHP-FPM 既不因并发不足产生 502/504,也不因进程过多导致内存吃紧或 OOM。


一、两种进程管理模式

参数 含义 适合场景
pm = static 固定数量子进程,使用 pm.max_children 流量稳定、内存可控、延迟敏感。
pm = dynamic 按需伸缩,使用 pm.start_serverspm.min_spare_serverspm.max_spare_servers 流量波动较大、希望平衡内存与并发。

老版本里 dynamic 也叫 apache-like,请以配置文件注释为准。


二、关键参数释义

  • pm.max_childrenstatic 下的固定进程数(dynamic 下是上限)。
  • pm.start_servers:启动时的子进程数(dynamic)。
  • pm.min_spare_servers:最小空闲进程数(dynamic)。
  • pm.max_spare_servers:最大空闲进程数(dynamic)。
  • pm.process_idle_timeout:空闲进程回收超时,建议 10–30s。
  • pm.max_requests:每个子进程处理多少请求后重启,用于缓解内存泄漏(常见 500–5000)。

三、容量规划方法(快速可落地)

  1. 测算单个 PHP 子进程内存占用:在业务低峰压一次接口,同时执行
    ps -o rss,cmd -C php-fpm | awk '{sum+=$1} END{print sum/NR/1024 " MB"}'

    得到 avg_child_mem(例如 40–80MB)。

  2. 给 PHP 预留可用内存php_mem_budget = 总内存 × 目标比例 - 其他服务保留
    • 示例:4GB 机器,给 PHP 预留 2.2GB,Nginx/MySQL/系统保留 1.8GB。
  3. 计算最大进程
    pm.max_children = floor( php_mem_budget / avg_child_mem )

    示例:2200MB / 50MB ≈ 44,取 40–44

  4. dynamic 推荐初值(经验法则):
    • pm.start_servers ≈ 0.2 × pm.max_children
    • pm.min_spare_servers ≈ 0.1–0.2 × pm.max_children
    • pm.max_spare_servers ≈ 0.4–0.6 × pm.max_children

注意:开启 opcache 会显著降低平均内存与 CPU 抖动;大并发上传/图片处理会临时抬升单进程内存,请留安全余量(10–20%)。


四、可直接使用的配置模板(军哥 LNMP)

编辑:/usr/local/php/etc/php-fpm.conf

模板 A:dynamic(推荐大多数网站)
; ====== 基础与日志 ======
error_log = /app/logs/php-fpm.log
log_level  = error
events.mechanism = epoll

; 监听与权限(与 Nginx 用户一致)
listen = 127.0.0.1:9000
; 或者:listen = /dev/shm/php-fpm.sock
; listen.owner = www
; listen.group = www
; listen.mode  = 0660

; ====== 进程管理 ======
pm = dynamic
pm.max_children = 52              ; 上限(由容量规划得出)
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 25
pm.process_idle_timeout = 20s
pm.max_requests = 2048

; ====== 慢日志 ======
slowlog = /app/logs/$pool.log.slow
request_slowlog_timeout = 10s

; ====== 资源限制 ======
rlimit_files = 32768
request_terminate_timeout = 100s
模板 B:static(低抖动、延迟敏感)
; 仅示例变化部分
pm = static
pm.max_children = 40      ; 固定进程数(容量规划计算值)
pm.max_requests = 2000
pm.process_idle_timeout = 0s

你文中的示例参数(如 pm.max_children = 52pm.start_servers = 5 等)是合理起点,但请按上文计算法结合同机内存与业务压力调整。


五、应用与验证

# 1) 语法自检
/usr/local/php/sbin/php-fpm -t

# 2) 平滑重载(推荐)
/usr/local/php/sbin/php-fpm -y /usr/local/php/etc/php-fpm.conf -t
kill -USR2 $(cat /usr/local/php/var/run/php-fpm.pid)  2>/dev/null || systemctl reload php-fpm

# 3) 查看进程与监听
ss -lntp | grep php-fpm
ps -ef | grep php-fpm

Nginx 配合(片段):

location ~ \.php$ {
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass 127.0.0.1:9000;  # 或 unix:/dev/shm/php-fpm.sock
    fastcgi_connect_timeout 60;
    fastcgi_send_timeout 180;
    fastcgi_read_timeout 180;
}

六、常见问题与排错

现象 可能原因 解决
502/Bad Gateway、日志 connect() failed PHP-FPM 未启动 / 监听不一致 / 权限不足 核对 fastcgi_passlisten;如用 sock,校验 owner/group/mode
504/Gateway Timeout PHP 执行过久或 Nginx fastcgi 超时偏小 优化代码/SQL;提高 fastcgi_read_timeout;调大 request_terminate_timeout
内存飙升/OOM pm.max_children 过大;脚本内存泄漏 重新估算上限;启用 pm.max_requests(1000–3000)并监控
队列堆积、响应慢 并发不足 增大 pm.max_children 与 spare;或启用 static,结合压测取点
慢日志大量记录 数据库/外部 API 慢 分析 $pool.log.slow,定位瓶颈(索引、连接池、网络)

七、调优建议清单

  • 开启 opcacheopcache.enable=1opcache.memory_consumption=128–256)。
  • 静态资源走 Nginx,PHP 勿做文件直传;上传用分片或异步后端。
  • 压测找“拐点”:逐步提高并发,观察 QPS、P95 延迟与 RSS/CPU 曲线。
  • 记录基线:变更前后保留 nginx access_logphp-fpm.log、系统监控。

附:你给出的示例参数说明(对照)

/usr/local/php/etc/php-fpm.conf

error_log = /app/logs/php-fpm.log
log_level  = error
events.mechanism = epoll

listen.owner = www
listen.group = www

pm.max_children = 52
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 25

pm.process_idle_timeout = 20s
pm.max_requests = 2048

slowlog = /app/logs/$pool.log.slow
rlimit_files = 32768
request_terminate_timeout = 100s
request_slowlog_timeout = 10s

查看进程:

ps -ef | grep fpm

FAQ

Q1:static 还是 dynamic 更好?

低抖动、延迟敏感、内存充足选 static;一般业务/流量有波动选 dynamic。核心仍是正确的容量规划。

Q2:pm.max_requests 设多少合适?

1000–3000 为常见区间;越大重启越少,越小更能抑制泄漏。结合慢日志与 RSS 曲线调节。

Q3:如何快速估算 pm.max_children?

用经验值 40–60MB/进程保守估算:上限 ≈ 可用内存(MB) / 50,上线后再根据实测 RSS 调整。


NO COMMENTS

LEAVE A REPLY

Please enter your comment!
Please enter your name here

退出移动版