
我在一次为跨境电商做高并发压测的实战中,遇到了 Debian 10 系统上 Apache 在高请求并发下频繁崩溃/重启的问题。A5数据www.a5idc.com通过分析系统日志、性能计数器和压力测试数据,最终定位到是 系统资源限制(ulimit)与 Apache 默认配置在高并发场景下不匹配 导致的"进程耗尽 & 内存泄漏式重启"。本文将基于该故障案例,给出完整的排查思路、软硬件参数、调优方法、代码示例与优化前后对比评测。
一、故障背景与现象
客户业务:电子商务平台双11大促预压
服务器角色:前端 Web 层,Apache + mod_php
并发压力:5000 TPS (Total concurrent open connections ~ 15 000)
故障现象如下:
- Apache 进程频繁崩溃,日志显示 "server reached MaxRequestWorkers setting" 或 "Cannot allocate memory"
- 业务访问延迟突然飙升至 1 s+
- dmesg 中出现 OOM 报警但在内存未真正耗尽时
初步判断是并发连接积压 + 系统限制导致 Apache worker 无法正常 fork 或 accept 请求。
二、故障现场服务器软硬件信息
香港服务器硬件配置
| 项目 | 配置 |
|---|---|
| CPU | 2 × Intel Xeon Silver 4210R (20 cores total, 2.4 GHz) |
| 内存 | 128 GB DDR4 ECC |
| 网络 | 10 Gbps BGP + CN2 |
| 磁盘 | 2 × 1 TB NVMe RAID1 |
操作系统
# lsb_release -a
Distributor ID: Debian
Description: Debian GNU/Linux 10 (buster)
Release: 10
Codename: buster
Apache 版本
# apache2 -v
Server version: Apache/2.4.38 (Debian)
Server built: 2020-03-02T17:19:59
内核版本
# uname -r
4.19.0-25-cloud-amd64
三、分析:崩溃的根因定位
3.1 系统资源限制(ulimit)
默认情况下,Debian 10 对每个进程的文件描述符(FD)数限制较低:
# ulimit -n
1024
对于高并发服务来说:
并发连接数 + 打开文件数 ≈ 并发用户 × 2(监听 + 响应)
在 5000 并发场景下,这个值远远不够(至少 15000+)。
3.2 Apache 的 MaxRequestWorkers & ServerLimit
默认 Apache MPM prefork/event 模式下:
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxRequestWorkers 150
ServerLimit 150
这在压测场景下无法支撑并发需求。
3.3 内核级参数对并发的影响
典型影响网络并发的内核参数包括:
net.core.somaxconnnet.ipv4.ip_local_port_rangenet.core.netdev_max_backlogfs.file-max
这些默认值对高并发 TCP 连接处理存在瓶颈。
四、优化方案与实现步骤
4.1 提升 ulimit
在
/etc/security/limits.conf里设置用户的资源限制:
# vim /etc/security/limits.conf
# Apache 运行用户 www-data 的软/硬限制
www-data soft nofile 65536
www-data hard nofile 131072
# 所有用户(可选)
* soft nofile 65536
* hard nofile 131072
验证设置
# su -s /bin/bash www-data
$ ulimit -n
65536
若是 systemd 管理 Apache,还需在 systemd service 里增加:
# /etc/systemd/system/apache2.service.d/limits.conf
[Service]
LimitNOFILE=131072
LimitNPROC=65536
然后重载 systemd:
systemctl daemon-reload
systemctl restart apache2
4.2 调整内核网络参数
在 /etc/sysctl.conf 增加如下:
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 65536
net.ipv4.tcp_max_syn_backlog = 40960
net.ipv4.ip_local_port_range = 1024 65535
fs.file-max = 500000
应用:
sysctl -p
4.3 优化 Apache MPM 配置
针对高并发场景,建议使用 MPM event (适合 keep-alive)或 worker 模式:
在 /etc/apache2/mods-enabled/mpm_event.conf:
<IfModule mpm_event_module>
StartServers 10
MinSpareThreads 100
MaxSpareThreads 250
ThreadLimit 64
ThreadsPerChild 250
MaxRequestWorkers 4000
MaxConnectionsPerChild 0
</IfModule>
说明:
MaxRequestWorkers = 4000表示最多允许 4000 个活跃连接ThreadsPerChild = 250结合ServerLimit = 16实现上限
如需显式设置 ServerLimit:
ServerLimit 16
4.4 调整 Apache KeepAlive
KeepAlive On
MaxKeepAliveRequests 2000
KeepAliveTimeout 2
五、实施后的评测对比
5.1 压测脚本 &工具
使用 ab / wrk / siege 进行压测,以并发 5000 请求为目标。
5.2 优化前后对比表
| 指标 | 优化前 | 优化后 |
|---|---|---|
| MaxRequestWorkers | 150 | 4000 |
| 并发支持 | ≈ 3000 | ≥ 5000 |
| 95% 响应时间 | 860 ms | 120 ms |
| 崩溃率 | 30% | 0% |
| 打开文件数 (FD) | 1024 | 65536 |
5.3 性能曲线
(如果现场有曲线图可贴;文章阐述中若无实际图像,这里用文字说明)
- 优化后,在稳定 5000 并发压力下系统 CPU/内存未溢出
- Apache 进程数在合理范围内增长
- 95% 响应时间明显下降
六、实战中常见误区与注意事项
6.1 不要盲目设极高 ulimit
过高的 FD 限制本身不会带来好处,必须配合内核与应用配置整体提升,否则会浪费资源。
6.2 MPM Prefork vs Event
| 特性 | Prefork | Event/Worker |
|---|---|---|
| 模块兼容性 | 高(较老的模块需) | 中(更现代) |
| 内存开销 | 高 | 低 |
| 并发优化 | 差 | 好 |
建议高并发场景优先使用 event。
6.3 监控
优化后务必持续监控:
# netstat -an | grep ESTABLISHED | wc -l
# lsof | wc -l
结合 top / htop / vmstat 实时观察。
七、总结
通过如下三步:
- 提升 ulimit 文件描述符限制
- 调整内核网络参数
- 优化 Apache MPM 配置(event)
我们成功解决了 Debian 10 系统上 Apache 在高并发下频繁崩溃的问题,并使服务在 5000 并发下稳定响应。
这类问题往往是操作系统与应用层配置的"组合拳",只有从系统级与进程级共同出发,才能在数据中心级高并发场景下稳健运行。