Windows Apache 最终配置清单与性能账:为什么一个字都不用再改
验收三件事全过:Syntax OK、两个 httpd.exe 父子链干净、CPU 与内存回落。下面是这份配置的逐条解读,以及它到底让网站变快了还是变慢了。
一、最终生效的配置
| 文件 | 指令 | 值 | 作用 |
|---|---|---|---|
| httpd.conf 第 535 行 | Include "conf/extra/httpd-default.conf" |
生效 | 加载默认参数文件;第 531 行带 # 的那份不生效,别被它骗了 |
| httpd-default.conf | Timeout |
30 | 本次真正止血的一条:中止永不返回的活跃请求 |
| httpd-default.conf | KeepAlive / MaxKeepAliveRequests / KeepAliveTimeout |
On / 100 / 3 | 接近默认值,空闲连接早释放,省线程 |
| httpd.conf 第 559-560 行 | AcceptFilter http noneAcceptFilter https none |
none | 避开防火墙、杀软、云锁类 agent 干扰 AcceptEx 导致的连接挂起 |
| httpd-mpm.conf | ThreadsPerChild |
64 | 并发上限,唯一有实质性能影响的改动 |
| httpd-mpm.conf | MaxConnectionsPerChild |
2000 | 非零回收,对付 PHP/第三方模块的内存泄漏 |
| httpd-mpm.conf | MaxMemFree |
2048 | 对 winnt 生效,与本次故障无关 |
二、看着像要改、其实都不用动
- prefork / worker / event / NetWare / OS2 五段:全部被
<IfModule>跳过,Windows 下是摆设,不用删。 MaxConnectionsPerChild改 800?不改。800 与 2000 是同一味药、只差 2.5 倍剂量;Windows 每次回收都要等TimeOut宽限、重建 64 个线程期间不接客,回收越频繁,撞上卡住请求的机会越多。官方对 Windows 的默认建议本来就是 0,非零只用于对付内存泄漏。- 开
mod_reqtimeout?不开。LoadModule reqtimeout_module被注释,RequestReadTimeout不生效;它管的是客户端慢速发请求头,管不了服务端 PHP 等后端不返回。 - AcceptFilter 的出处:依据在 Apache 官方
mpm_winnt文档,不是 XAMPP 官方 FAQ;2.4 起用AcceptFilter ... none取代 2.0/2.2 的Win32DisableAcceptEx,把老指令抄进 2.4 会直接起不来。 - 指令名:文件里已是新名
MaxConnectionsPerChild,不用换回旧名;真实配置中也没有行尾#注释这种语法坑。
三、正确的重启姿势
别用面板 Restart,也别用 httpd -k restart,Windows 服务模式下容易留下孤儿进程。用「停服务 → 确认清空 → 单入口启动」:
$f = 'C:\xampp\apache\conf\httpd.conf'
if (-not (Select-String -Path $f -Pattern '^\s*AcceptFilter')) {
Add-Content $f "`nAcceptFilter http none`nAcceptFilter https none"
}
& C:\xampp\apache\bin\httpd.exe -t
$s = (Get-Service | Where-Object Name -Match 'apache' | Select-Object -First 1).Name
Stop-Service $s -Force
taskkill /F /IM httpd.exe /T 2>$null
Start-Service $s
Get-CimInstance Win32_Process -Filter "Name='httpd.exe'" | Select-Object ProcessId,ParentProcessId
7384 ← 560、1680 ← 7384。PID 与上一次不同,说明旧进程确实清干净后全新启动。
四、会不会影响网页访问速度
| 改动 | 对速度的影响 | 什么时候才感觉得到 |
|---|---|---|
Timeout 30 |
正常页面零影响 | 慢网上传、大文件下载停顿超过 30 秒会被断 |
| KeepAlive 三项 | 几乎无感,反而省线程 | 基本感觉不到 |
AcceptFilter none |
理论有细微开销:改用 accept()、不复用 socket |
高并发短连接场景;换来不被网络层干扰而挂起 |
ThreadsPerChild 150 → 64 |
唯一实质影响 并发上限降低 | 同一瞬间请求超过 64 个开始排队、TTFB 变长;低流量站点无感 |
MaxConnectionsPerChild 2000 |
每 2000 连接一次极短空窗 | 流量大时偶发;若又碰到卡住的请求会等满宽限,那时才明显 |
| 两次重启 | 一次性中断,已结束 | 无 |
五、唯一需要回头动参数的情况
ThreadsPerChild 调到 100(别一步跳回 150),走上面那套完整 stop → 确认清空 → start。除此之外一个字别改。
别为了「提速」做这三件蠢事:把 AcceptFilter 删回去、把 MaxConnectionsPerChild 改成 800 或 0、去开 mod_reqtimeout。都跟这次的速度无关。
access.log 找耗时几十秒的 URL。