Apache并发调优需先确认MPM类型,再按event/prefork等模型调整MaxRequestWorkers等参数,并同步优化ulimit和内核参数以避免系统限制;最后通过压测和状态监控验证效果。

Apache 默认的并发连接数远低于现代 Web 服务的实际需求,不调优会导致大量请求排队、超时甚至 503 错误;但盲目调高又可能耗尽内存或触发内核限制,必须结合 MPM 类型、可用内存和系统资源综合调整。
确认当前使用的 MPM 模块类型
Apache 的并发模型由 MPM(Multi-Processing Module)决定,prefork、worker 和 event 行为差异极大,直接决定你能调哪些参数:
-
prefork:每个请求独占一个进程,MaxRequestWorkers是核心上限,但内存开销大,适合 PHP-CGI 等非线程安全环境 -
worker和event:多线程 + 多进程混合,MaxRequestWorkers实际是线程总数上限,需同时控制ThreadsPerChild和ServerLimit - 运行
httpd -V | grep -i mpm或apache2ctl -V | grep -i mpm查看当前启用模块 - Debian/Ubuntu 默认多为
event,CentOS 7+ 默认也是event,但旧版可能仍用prefork
修改关键并发参数(以 event MPM 为例)
event 是目前推荐的高并发 MPM,它用少量线程处理大量连接(尤其对 Keep-Alive 和空闲连接更友好),但配置稍复杂:
- 编辑 MPM 配置文件:
/etc/apache2/mods-available/mpm_event.conf(Debian/Ubuntu)或/etc/httpd/conf.modules.d/00-mpm.conf(RHEL/CentOS) - 重点调整以下三项(单位均为整数,非字节或秒):
-
StartServers:启动时创建的子进程数,建议设为 CPU 核心数 -
MaxRequestWorkers:全局最大并发请求数,不能超过ServerLimit × ThreadsPerChild -
ThreadsPerChild:每个子进程创建的线程数,通常设为 25–100;值越大单进程负载越高,但线程切换开销也上升
-
- 示例(16G 内存、4 核服务器):
StartServers 4 MinSpareThreads 25 MaxSpareThreads 75 ThreadsPerChild 50 MaxRequestWorkers 400 ServerLimit 8
→ 此时最大线程数 =
ServerLimit × ThreadsPerChild= 8 × 50 = 400,与MaxRequestWorkers一致
绕过系统级限制:ulimit 和内核参数
即使 Apache 配置调高,Linux 默认的进程文件描述符限制(ulimit -n)和 epoll 相关内核参数不足,也会导致“Too many open files”错误或连接被静默丢弃:
- 检查当前限制:
ulimit -n(用户级)、cat /proc/$(pgrep apache2 | head -1)/limits | grep "Max open files"(实际生效值) - 永久提升 Apache 用户限制:
- 在
/etc/systemd/system/multi-user.target.wants/apache2.service(Debian)或/usr/lib/systemd/system/httpd.service(RHEL)中添加:[Service] LimitNOFILE=65536
- 然后执行
systemctl daemon-reload && systemctl restart apache2
- 在
- 必要时调大内核参数(仅当并发 > 10k 且出现
accept queue overflow):-
net.core.somaxconn:监听队列长度,建议设为 65535 -
net.ipv4.ip_local_port_range:临时端口范围,设为1024 65535 - 写入
/etc/sysctl.conf后运行sysctl -p
-
验证是否生效 & 容易被忽略的点
改完配置重启后,别只信 systemctl status —— 很多问题在真实压测时才暴露:
- 用
ab -n 1000 -c 500 http://localhost/或wrk -t4 -c1000 -d10s http://localhost/观察响应时间和失败率 - 实时查看工作状态:
sudo apache2ctl status(需启用mod_status)或sudo ss -s | grep "tcp:"看 ESTAB 连接数 - 最容易被忽略的是
MaxConnectionsPerChild:设得太小(如默认 10000)会导致频繁进程回收,CPU 升高;设为 0 表示永不回收,但要注意内存缓慢泄漏风险 - 如果用了反向代理(如 Nginx 前置),Apache 的并发压力会显著降低,此时过度调优反而浪费资源

















