调整 Apache 的MaxConnectionsPerChild参数可强制子进程在处理指定数量请求后重启,从而释放累积内存。该参数在 event 或 worker MPM 模式下生效,prefork 模式下对应参数为MaxRequestsPerChild,建议值通常在 1000 至 20000 之间,修改后必须重启 Apache 服务而非热重载。
先说结论:通过限制子进程生命周期防止内存泄漏,需根据 MPM 模式选择参数名并重启服务生效。
- 适合场景:Apache 子进程 RSS 内存随时间单向爬升且无法自动释放。
- 先做准备:使用
httpd -V确认 MPM 模式,备份当前配置文件。 - 验收标准:观察
ps aux中 httpd 进程 RSS 波动稳定,mod_status中 CPs 字段周期性归零。
命令速用版
以下命令用于快速确认运行模式并重启服务,配置修改需在配置文件中进行。
# 确认 MPM 模式
httpd -V | grep -i mpm
# 重启 Apache 使配置生效(CentOS/RHEL)
systemctl restart httpd
# 重启 Apache 使配置生效(Debian/Ubuntu)
systemctl restart apache2为什么会这样
子进程长期运行会导致内存无法释放,因为 PHP 变量未释放或扩展模块引用未清理会累积占用。
Apache 子进程在处理大量请求后,可能因代码逻辑或第三方库缓存导致内存占用缓慢上升。MaxConnectionsPerChild设定每个子进程最多服务多少个请求后就自动退出,进程终止时操作系统会回收其全部内存,相当于一次强制重置。该机制不直接修复泄漏代码,而是通过主动回收进程切断内存持续增长路径。
分步处理
按以下步骤调整参数,确保配置与当前 MPM 模式匹配。
1. 确认 MPM 模式
运行httpd -V | grep -i mpm或apachectl -l | grep mpm。若输出含mpm_prefork_module,需使用MaxRequestsPerChild参数;若为mpm_event_module或mpm_worker_module,使用MaxConnectionsPerChild。
2. 计算合理数值
根据服务器内存规模设定值。轻量服务器(≤4GB 内存)建议 100–250,中型服务器(4–16GB)建议 250–500,大型服务器(≥16GB)建议 500–1000。若使用 event/worker 模式,典型合理范围为 5000–20000,需结合日志中单进程内存增长速率判断。值设得太小会增加 fork 开销导致 CPU 使用率升高,值设得太大起不到及时释放作用。
3. 修改配置文件
编辑/etc/httpd/conf/httpd.conf或/etc/apache2/apache2.conf,或在/etc/httpd/conf.d/下的 mpm 配置文件。在对应的<IfModule>块中添加或修改:
<IfModule mpm_event_module>
MaxConnectionsPerChild 10000
</IfModule>
<IfModule mpm_prefork_module>
MaxRequestsPerChild 1000
</IfModule>4. 重启服务
修改后必须执行systemctl restart httpd或systemctl restart apache2。热重载(reload)不会重置已运行进程的计数器,无法立即生效。
怎么验证是否生效
通过监控进程内存和连接计数确认参数是否起作用。
1. 检查进程内存
使用ps aux `--sort`=-%mem | head -10查看 httpd 进程内存排序。关注 RSS 是否随时间稳定波动而非单向爬升。若设置生效,旧进程消失后新进程内存应从初始值开始。
2. 检查状态模块
开启 Apache 状态模块(mod_status),访问/server-status?auto。检查CPs(Connections per child)字段是否接近设定值并周期性归零。若 CPs 持续增加不归零,说明参数未生效或模式不匹配。
常见坑
配置调整时需注意参数名称差异和服务重启方式,避免无效操作。
1. 参数名称混淆
Apache HTTP Server 2.3.9 及更高版本中已将MaxRequestsPerChild更名为MaxConnectionsPerChild,但在 prefork 模式下旧名称仍常被引用。若配置后无效,请检查当前 MPM 模式是否匹配参数名。
2. 仅重载未重启
执行systemctl reload不会终止已运行的子进程,计数器不会重置。必须执行restart或完全 stop 后再 start 才能强制回收当前内存。
3. 值设置过小
若设为 50 或 100 等极小值,进程频繁启停会增加 fork 开销,导致 CPU 使用率升高。除非内存极度紧张(如 1G VPS),否则不建议低于 1000。
常见问题
MaxConnectionsPerChild 设置为 0 是什么意思?
设置为 0 表示子进程永不退出,长期运行后可能因模块缺陷累积内存。
Prefork 模式下应该用哪个参数?
Prefork 模式下对应参数是MaxRequestsPerChild,部分新版文档也通用MaxConnectionsPerChild,但建议优先使用MaxRequestsPerChild以确保兼容。
调整该参数能修复代码内存泄漏吗?
不能,该机制仅通过重启进程释放内存,若请求本身触发严重泄漏,仍需检查代码中大对象释放或数据库连接管理。
参考来源
- 如何通过调整 MaxConnectionsPerChild 防止内存泄露
- 如何通过调整 Apache 的 MPM 参数优化内存占用
- Java 中 Apache 在 Prefork 架构下的内存管理与优化方案
- 如何设置 Apache 核心参数 MaxClients 与 MaxRequestsPerChild
- Apache 配置时如何调整内存使用
- 解决 Apache 服务器内存占用高的问题
- apache 在 centos 上如何调整内存使用
- CentOS 中如何优化 Apache 内存使用
- 怎样优化 Apache 的连接数设置