应优先选用 event mpm,因其事件驱动+线程池模型可高效处理长连接与高并发;prefork 因内存开销大、并发低且仅适用于旧版 mod_php,现代 php-fpm 等反向代理场景下已无存在必要;worker 仅适用于老系统或特定线程安全问题场景。

Apache 的 MPM(Multi-Processing Module)不是“选一个就行”的配置项,而是直接影响并发能力、内存占用和稳定性的一线决策——prefork、worker、event 三者不能混用,且一旦模块不匹配后端应用模型(比如 PHP-CGI vs PHP-FPM vs Node.js 反向代理),轻则连接堆积,重则 Apache 进程崩溃或响应超时。
为什么 prefork 在现代业务中基本该被排除
prefork 是纯进程模型:每个请求独占一个 httpd 进程,无共享内存,线程安全但资源开销极大。它唯一不可替代的场景是运行非线程安全的模块(如旧版 mod_php 直接嵌入 Apache)。但今天几乎所有 PHP 部署都走 php-fpm + proxy_fcgi,此时 prefork 的进程隔离优势消失,而其内存浪费(每个进程常驻 10–30MB)和低并发上限(通常卡在 256–512 并发)反而成为瓶颈。
- 典型错误现象:
scoreboard中大量_(空闲)和S(已启动但未服务)状态并存,ps aux | grep httpd显示上百个低负载进程 - 如果你用的是
PHP-FPM、uWSGI、Gunicorn或任何反向代理后端,prefork没有存在必要 - 兼容性无优势:所有主流 Linux 发行版默认启用
event,prefork反而因禁用AcceptFilter和Sendfile影响静态文件性能
event 是绝大多数 HTTP/HTTPS 服务的默认选择
event 是 Apache 2.4+ 默认 MPM,基于事件驱动 + 线程池混合模型,能高效处理长连接(如 WebSocket、HTTP keep-alive)、慢速客户端和大量空闲连接。它把连接监听、SSL 握手、请求读取等 I/O 密集型任务交给单独的“监听线程”,工作线程只负责处理已就绪的请求,因此单机支撑 5k+ 并发很常见。
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
- 必须关闭
mod_mpm_prefork并启用mod_mpm_event;确认加载顺序:MPM 模块必须在其他模块之前加载 - 关键调优参数:
ThreadsPerChild(建议 25–50)、MaxRequestWorkers(=ThreadsPerChild×ServerLimit,不要超过系统 ulimit -u)、MaxConnectionsPerChild(设为 0 表示永不过期,避免频繁 fork 开销) - 注意 SSL 场景:若使用 OpenSSL 1.0.2 或更老版本,
event在高并发 TLS 握手时可能因锁竞争退化为worker行为;升级到 OpenSSL 1.1.1+ 可解除限制
什么情况下还得退回 worker
worker 是线程模型(每个进程含多线程),比 prefork 节省内存,但不如 event 抗长连接。它的实际价值只剩两个窄场景:一是运行极老内核(如 RHEL6/CentOS6)且无法升级 Apache;二是后端应用本身严重依赖线程局部存储(TLS)或存在未修复的线程安全 bug(例如某些定制 C 模块未加锁)。
- 常见误判:看到 “
worker支持线程” 就以为它适合高并发 —— 实际上它对慢速客户端和 keep-alive 连接处理效率远低于event,容易出现timeout或connection reset - 配置上必须设置
EnableExceptionHook on,否则线程崩溃会导致整个进程退出,影响可用性 - 若你用的是 Python/Java/Go 后端且走反向代理,
worker和event在功能上完全等价,但event的连接复用率更高、内存更稳
真正棘手的从来不是选哪个 MPM,而是 MPM 和后端通信方式是否对齐:比如用 event 却配了阻塞式 mod_proxy_http + 后端响应慢,连接就会卡在 Apache 线程池里;又或者开了 KeepAliveTimeout 5 却让后端主动断连,导致 Apache 线程长时间等待 FIN。这些细节比 MPM 本身更容易拖垮服务。










