Windows 下 Nginx 无法使用 epoll 是系统级硬伤,只能退至 select 或 poll;select 硬限 1024 连接,poll 超 8000 后性能骤降;调高 worker_connections 无效,因底层事件模型不支持高效轮询。

Windows 平台下 Nginx 无法使用 epoll,这不是配置能绕过的限制,而是系统级硬伤。epoll 是 Linux 内核原生机制,Windows 没有等效实现,Nginx 在该平台只能退回到 select 或 poll —— 前者硬限 1024 连接,后者虽可突破但性能随连接数线性下降,实测超过 8000 后延迟明显升高、CPU 持续飙高。
为什么改 worker_connections 数值没用
你把 worker_connections 设成 65535,Nginx 可能启动成功,但真实并发卡在 800–1500;日志里频繁出现 accept() failed (10038) 或 connect() failed (10061);用 netstat -an | findstr :80 | findstr ESTABLISHED 查到的活跃连接远低于理论值。这是因为底层事件模型不支持高效轮询,不是参数没调对,是根本跑不起来。
换用 poll 模式 + 定制版 nginx.exe(仅限开发/测试场景)
这是 Windows 下唯一可行的“软升级”路径,但需三步同步操作:
- 下载支持 poll 的非官方 Windows 版 Nginx(如 nginx-win.ecsds.eu 提供的 nginx_basic.exe),替换 phpEnv 或原生安装包里的 nginx.exe
- 运行配套注册表脚本 Tweak-Optimize tcpip parameters for nginx connections.reg,扩大系统级句柄与端口范围
- 在 nginx.conf 的 events 块中显式声明:
events {<br> use poll;<br> worker_connections 8192;<br> multi_accept on;<br>}
注意:worker_processes 必须设为 1,设 auto 或大于 1 会被忽略或报错
真正面向生产的替代方案
如果目标是稳定、可观测、可扩缩的线上服务,就不要在 Windows 上强撑 Nginx:
-
WSL2 + 原生 Linux Nginx:启用 WSL2(如 Ubuntu 22.04),直接 apt install nginx。它获得完整 epoll 支持、多 worker 进程、热重载、模块生态,同时仍能访问
/mnt/c/下的项目文件 -
Docker Desktop 运行官方 nginx:alpine:通过
docker run -d -p 80:80 -v ./conf:/etc/nginx/conf.d nginx:alpine启动,完全隔离 Windows 内核限制,日志直出 stdout,配置即代码 - 反向代理层下沉:用 Caddy(原生支持 Windows + 自动 HTTPS + 零配置 TLS)或 Traefik(内置服务发现)做前端入口,Nginx 仅作为后端轻量转发器,规避其高并发短板
别踩的典型误区
这些做法看似优化,实则无效甚至有害:
- 修改系统 FD_SETSIZE 或尝试 patch select —— Windows 的 select 实现是内核硬编码,不可覆盖
- 在 phpEnv 等集成包里只改配置不换二进制 —— 它们默认打包的是标准 select 版 nginx.exe,改了也白改
- 盲目提高 keepalive_timeout 或开大 sendfile —— 在 poll 模型下,长连接反而加剧句柄堆积和遍历开销
- 指望 Swoole 原生支持 Windows —— 它依赖 epoll/kqueue,官方至今不支持,仅能靠 Swoole-CLI 或 WSL2 间接运行



















