首要原因是php.ini加载了大量用不到的扩展,应禁用imap、ldap、pgsql等非必要模块;必须开启OPcache并合理配置内存与文件数;FPM宜用static模式并限制max_children=3;静态资源须由Nginx直接处理。

PHP 模块太多导致启动慢、内存高
低配服务器(比如 1GB 内存、单核 CPU)跑 PHP 源码卡顿,首要原因是 php.ini 里加载了大量用不到的扩展。每个扩展都会占用内存、延长 PHP 初始化时间,尤其在 CGI/FPM 模式下,worker 进程反复加载更明显。
实操建议:
- 运行
php -m查看已启用模块,对照项目实际需求逐个排查;常见可禁用项:imap、ldap、pgsql、snmp、soap(除非你真在调用邮件服务、LDAP 认证、PostgreSQL、SNMP 监控或 WebService) - 在
php.ini中注释掉对应extension=xxx.so行,或改用disable_functions屏蔽函数级功能(如disable_functions = exec,passthru,shell_exec,system) - 重启
php-fpm或 Web 服务后,用php -v和top -p $(pgrep php-fpm)观察内存占用是否下降
OPcache 不开等于裸跑 PHP
没有 OPcache,每次请求都要重新解析、编译 PHP 文件为 opcode,对低配机是灾难性开销。默认 PHP 7.0+ 虽带 OPcache,但常处于 disabled 状态或配置极保守。
关键配置项(在 php.ini 中确认):
立即学习“PHP免费学习笔记(深入)”;
-
opcache.enable=1(必须开启) -
opcache.memory_consumption=64(小内存机器设 32–64 MB 即可,别盲目调大) -
opcache.max_accelerated_files=4000(源码文件数少于 2000 时可降到 2000) -
opcache.revalidate_freq=60(开发环境可设为 2,生产环境建议 ≥60,避免频繁校验) -
opcache.validate_timestamps=1(上线后若代码不热更,可设为 0 提升性能,但需手动opcache_reset()或重启 fpm)
验证是否生效:访问 phpinfo() 页面搜索 “OPcache”,或执行 php -r "print_r(opcache_get_status());"
FPM 进程模型压根不适合低配机
默认 pm=dynamic 配置常保留过多空闲进程,1GB 内存下极易被 OOM Killer 干掉。更糟的是,pm.max_children 若设为 10+,每个 PHP-FPM worker 实际吃掉 20–40MB 内存,瞬间爆满。
推荐精简配置(/etc/php/*/fpm/pool.d/www.conf):
-
pm = static(避免动态伸缩开销,更可控) -
pm.max_children = 3(Nginx 并发连接数 ≤ 500 时足够;超了宁可加fastcgi_buffer也不盲目加 children) -
pm.start_servers = 2(static 模式下该值无效,但保持与 max_children 一致更清晰) -
pm.max_requests = 500(防内存泄漏累积,低配机建议值,别设 0) - 顺手关掉
slowlog和access.log(除非调试需要)
静态资源没走缓存,PHP 白扛压力
很多 PHP 源码(尤其是 CMS 或框架)默认把 CSS/JS/图片也交给 PHP 脚本分发,比如 index.php?file=style.css。这会让 FPM 进程无谓处理本该由 Nginx 直接响应的请求。
必须做的两件事:
- Nginx 配置中显式声明静态资源路径,例如:
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
} - 检查 PHP 源码里是否用了
readfile()或file_get_contents()输出前端资源——这类逻辑应直接删掉或重写为纯静态路径引用 - 确认
favicon.ico不是由 PHP 脚本生成(常见于 Laravel、ThinkPHP 的路由兜底逻辑),否则每个页面请求都额外触发一次 PHP 执行
真实瓶颈往往不在 PHP 本身,而在“本不该它干的事它全干了”。低配服务器上,少一次 PHP 解析,就少一次内存分配和 opcode 编译——这些损耗加起来,比调优一个 SQL 还明显。











