关键是强制使用prefork模式——它用进程隔离代替线程共享,天然绕过非线程安全(nts)扩展的崩溃风险;需确认mpm为prefork、禁用其他mpm模块、加载libphp.so并配置addhandler,且不混用php-fpm。

要让老PHP脚本在Apache上稳定运行,关键是强制使用Prefork模式——它用进程隔离代替线程共享,天然绕过非线程安全(NTS)扩展的崩溃风险。不改PHP代码、不重写扩展,靠调整Apache底层模型就能解决。
确认并切换到Prefork MPM
别只看配置文件,直接查当前生效的MPM:
- 运行 httpd -V(CentOS/RHEL)或 apache2ctl -V(Debian/Ubuntu),找输出中 MPM: prefork 这一行
- 如果显示 event 或 worker,说明还没切成功
- Debian/Ubuntu:先执行 a2dismod mpm_event(或 mpm_worker),再执行 a2enmod mpm_prefork,最后 systemctl restart apache2
- CentOS/RHEL:编辑 /etc/httpd/conf.modules.d/00-mpm.conf,注释掉 mpm_event_module 和 mpm_worker_module,取消注释 mpm_prefork_module
验证模块加载无冲突
即使启用了Prefork,若其他MPM模块仍被加载,它们会悄悄覆盖配置:
- 运行 apache2ctl -M | grep mpm(Debian)或 httpd -M | grep mpm(CentOS)
- 输出里应只有 mpm_prefork_module (shared)
- 如果同时看到 mpm_event_module 或 mpm_worker_module,说明禁用没生效,需回退检查 a2dismod 或 conf.modules.d 配置
适配PHP运行方式
Prefork本身不运行PHP,它只是为 mod_php 提供安全的进程环境:
- 确保已加载 libphp.so(路径如 /usr/lib/apache2/modules/libphp.so 或 /usr/lib64/httpd/modules/libphp.so)
- 在配置中加入:AddHandler php-script .php 和
SetHandler application/x-httpd-php - 不要混用 PHP-FPM:Prefork + mod_php 是经典组合;Prefork + PHP-FPM 属于资源错配,每个进程都维持FCGI连接,反而增加开销
调优Prefork参数防内存溢出
老PHP脚本常因扩展内存泄漏严重,参数设错会导致频繁崩溃或OOM:
- StartServers:设为 4–8,避免冷启动拉起过多空进程
- MaxRequestWorkers:这是硬上限,按公式估算:总可用内存 × 0.7 / 单个httpd进程平均RSS值;用 ps aux --sort=-%mem | grep httpd | head -3 查RSS中位数
- MaxConnectionsPerChild:设为 5000–10000,太小导致频繁fork,太大可能累积泄漏
- 每次修改后务必运行 apachectl configtest 检查语法,再用 systemctl reload apache2 平滑生效
这套配置不依赖PHP版本升级或扩展重编译,专为无法重构的遗留系统设计。核心就三点:MPM必须是prefork、不能有其他MPM共存、PHP必须走mod_php嵌入式加载。做完这些,OCI8、旧MySQLi、自定义C扩展都能照常跑。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











