apache高并发报“too many open files”本质是进程文件句柄限制过低(默认1024),需通过limits.conf和systemd配置提升至65535,并同步调优内核参数如somaxconn、tcp_tw_reuse等,最后验证进程limits及连接状态。

Apache 在高并发下报 “Too many open files”,本质不是 Apache 配置错了,而是它启动时继承的文件句柄限制太低——默认 1024 个,连 1000 个并发连接都撑不住。真正起作用的,是操作系统对进程的限制,不是 httpd.conf 里的 MaxRequestWorkers。
查清楚当前限制在哪卡住
别猜,直接看进程实际能用多少:
- 查 Apache 进程真实限制:cat /proc/$(pgrep apache2 | head -1)/limits | grep "Max open files" —— 若显示 1024 1024,说明根本没放开
- 查系统全局上限:cat /proc/sys/fs/file-max —— 若低于 50 万,也得调
- 查当前 TIME_WAIT 连接堆积:ss -s | grep tcp —— 若大量处于 TIME_WAIT,说明连接回收慢,会持续占着句柄
永久放宽 Apache 进程的句柄上限
Apache 通常以 www-data 或 apache 用户运行,必须针对该用户设限,且 systemd 启动方式需额外处理:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
- 编辑 /etc/security/limits.conf,追加两行(不能只写 soft):
www-data soft nofile 65535
www-data hard nofile 65535 - 若用 systemd(几乎所有现代发行版),再建覆盖配置:
sudo mkdir -p /etc/systemd/system/apache2.service.d
sudo nano /etc/systemd/system/apache2.service.d/limits.conf
内容写:
[Service]
LimitNOFILE=65535 - 重载并重启:sudo systemctl daemon-reload && sudo systemctl restart apache2
同步调优内核网络参数
光放开句柄不够,连接队列、TIME_WAIT 回收、缓冲区不跟上,照样卡在握手或丢包:
- 编辑 /etc/sysctl.conf,加入以下几项:
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
fs.file-max = 2097152 - 执行 sudo sysctl -p 立即生效
- 注意:tcp_tw_reuse 要求 net.ipv4.tcp_timestamps = 1(默认已开启),公网服务器可放心用;若前端有 NAT 或老旧代理,需验证兼容性
验证是否真生效
改完不验证等于白改。重点看进程本身,不是终端:
- 重启后立刻执行:cat /proc/$(pgrep apache2 | head -1)/limits | grep "Max open files"
输出应为 65535 65535(两列数值一致才表示 hard limit 生效) - 压测时观察:lsof -p $(pgrep apache2 | head -1) | wc -l —— 实际打开数应能稳定接近 65535,且不再出现 “Too many open files” 错误日志
- 检查连接状态:ss -tan state established | wc -l 和 ss -tan state time-wait | wc -l,确认 ESTABLISHED 上升、TIME_WAIT 不持续堆积










