Apache 高并发下 MPM 用 prefork 还是 worker 性能更好?

文章导读
在高并发场景下,通常 worker 模式比 prefork 能更好地利用内存并处理更多连接,但如果你使用的是非线程安全的模块(如旧版 mod_php),prefork 仍是必须的选择。现代 Apache 版本中,event 模式往往是高并发下的更优解。
📋 目录
  1. 如何准确确认当前 MPM 模式
  2. Prefork 与 Worker 的核心差异
  3. 切换 MPM 配置步骤
  4. 性能验证与状态检查
  5. 高风险场景与常见坑
  6. 参考来源
A A

在高并发场景下,通常 worker 模式比 prefork 能更好地利用内存并处理更多连接,但如果你使用的是非线程安全的模块(如旧版 mod_php),prefork 仍是必须的选择。现代 Apache 版本中,event 模式往往是高并发下的更优解。

先说结论:追求并发性能和内存效率选 worker 或 event,追求兼容性和稳定性选 prefork。

  • 适合:内存受限、连接数高的 Web 服务
  • 重点看:所加载模块是否支持线程安全
  • 别忽略:Apache 2.4 后 event MPM 通常比 worker 更适合高并发

如何准确确认当前 MPM 模式

命令 httpd -V 仅显示编译时的默认设置,不一定代表当前运行状态。确认运行时 MPM 模式更可靠的方法如下:

1. 查看错误日志(推荐)

重启 Apache 后,查看错误日志启动信息,通常会明确记载加载的 MPM 模块:

grep "MPM" /var/log/httpd/error_log
# 或 Debian/Ubuntu 体系
grep "MPM" /var/log/apache2/error.log

2. 观察进程结构

使用 ps 命令观察进程与线程关系,prefork 是多进程,worker 是多进程多线程:

ps -eLf | grep httpd | wc -l
# 如果进程数少但线程数多,通常为 worker 或 event 模式
# 如果进程数多且每个进程线程数为 1,通常为 prefork 模式

Prefork 与 Worker 的核心差异

Apache 的 MPM(多处理模块)决定了服务器如何处理请求。prefork 是多进程模型,每个请求独占一个进程,稳定性高但内存开销大;worker 是多进程多线程模型,多个线程共享进程内存,并发能力更强但要求所有加载的模块必须是线程安全的。

架构上 worker 在相同内存下能维持的活跃连接数通常更多,因为线程比进程消耗更少的内存资源。如果模块不兼容线程,worker 模式下容易出现随机崩溃或数据错乱。

切换 MPM 配置步骤

切换 MPM 需要修改配置并重启服务,操作前请确保有回滚方案。

1. 备份配置文件

cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.bak
# 或 Debian/Ubuntu 体系
cp /etc/apache2/apache2.conf /etc/apache2/apache2.conf.bak

2. 修改 MPM 配置

在配置文件中找到 LoadModule 指令,注释掉当前的 mpm 模块,启用目标模块。例如从 prefork 切换到 worker:

# LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
LoadModule mpm_worker_module modules/mod_mpm_worker.so

部分发行版使用 a2dismod 和 a2enmod 管理:

Apache 高并发下 MPM 用 prefork 还是 worker 性能更好?
a2dismod mpm_prefork
a2enmod mpm_worker

3. 检查配置语法

httpd -t
# 或
apachectl configtest

显示 Syntax OK 后再重启,否则不要重启。

4. 重启服务

systemctl restart httpd
# 或
systemctl restart apache2

性能验证与状态检查

重启后通过压力测试对比切换前后的承载能力,并观察系统资源。

1. 简单并发测试

使用 ab 工具进行简单压测,观察 Requests per second 和 Failed requests:

ab -c 100 -n 1000 http://localhost/

2. 资源监控

  • 使用 tophtop 查看 httpd 进程数是否减少,线程数是否增加。
  • 查看错误日志 error_log,确认没有关于线程安全或段错误(Segmentation Fault)的报错。
  • 在高负载测试下,观察内存增长是否比之前平缓。

高风险场景与常见坑

1. PHP 处理方式冲突(高危)

如果你使用 mod_php 且版本较旧,它通常不是线程安全的,强制使用 worker 会导致 Apache 崩溃。务必确认 PHP 模块兼容性。这种情况下要么继续用 prefork,要么改用 PHP-FPM 模式配合 proxy_fcgi 模块,这样才能安全地使用 worker 或 event 模式。

2. 第三方模块兼容性

某些旧版第三方模块可能未标注是否线程安全。切换后如果出现随机 500 错误或进程退出,优先怀疑模块兼容性问题。请勿使用 httpd -M | grep thread 判断安全性,该命令无效,需查阅模块官方文档。

3. 忽略 event 模式

在 Apache 2.4 及更高版本中,event MPM 解决了 worker 模式下 keep-alive 连接占用线程的问题。如果是全新部署或可升级版本,建议直接评估 event 模式而非 worker。

参考来源

  • Apache HTTP Server 官方文档 - MPM 比较页面,标题:MPM Common Directives,URL:https://httpd.apache.org/docs/2.4/mod/mpm_common.html
  • Apache HTTP Server 官方文档 - Prefork 说明,标题:mod_mpm_prefork,URL:https://httpd.apache.org/docs/2.4/mod/prefork.html
  • Apache HTTP Server 官方文档 - Worker 说明,标题:mod_mpm_worker,URL:https://httpd.apache.org/docs/2.4/mod/worker.html