Nginx 的异步事件驱动模型通过非阻塞 I/O 与 epoll/kqueue 结合,使单 worker 进程可高效管理数万连接:I/O 调用立即返回(EAGAIN),事件就绪时才处理,避免阻塞等待,全程无空轮询,CPU 与内存开销极低。

异步事件驱动让 Nginx 不再“干等”,而是把原本浪费在 I/O 等待上的时间腾出来处理其他请求,资源利用率因此大幅提升。
一个进程盯住成千上万连接,不为每个连接单独开销
传统服务器(比如 Apache prefork)每来一个连接就 fork 一个新进程,每个进程都要分配栈空间、维护上下文;而 Nginx 的 worker 进程用 epoll 或 kqueue 同时监听数万 socket,连接建立后不生成新进程/线程,只在数据可读、可写或连接关闭时才被唤醒——没事件时,它就在循环里空转等待内核通知,不消耗 CPU,也不占额外内存。
非阻塞 I/O 配合状态机,避免卡在某一步
所有 socket 都设为非阻塞模式:read/write 调用立即返回,若无数据就返回 EAGAIN。Nginx 不会停下来等,而是把当前请求挂起,记录当前处理阶段(比如“已收完 header,正在等 body”),继续轮询其他就绪事件。等下次 epoll_wait 通知该 socket 可读了,再接着上次状态往下走。
- 一次 accept 可能带出多个新连接
- 一次 recv 可能只读到部分 HTTP 头
- 一次 send 可能只发出响应体的一部分
事件循环全程无阻塞调用
Nginx 默认规避所有可能阻塞的操作:
- DNS 解析走异步 resolver,不调用 gethostbyname 这类同步函数
- 日志写入启用 buffer 和 async,避免阻塞主线程
- 静态文件发送优先用 sendfile,由内核直接在磁盘页缓存和 socket 间搬运,不经过用户态内存拷贝
- 不加载 Lua 模块中含阻塞 API 的代码,也不开启 autoindex、ssi 等增加路径复杂度的模块
减少锁争用与系统级配合
高并发下,accept 阶段容易成为瓶颈。关闭 accept_mutex 并配合内核的 SO_REUSEPORT,能让多个 worker 进程各自独立接受连接,避免串行抢锁;同时必须调高系统级限制:
- 设置 worker_connections 为 65535 或更高
- 同步调整 ulimit -n,确保文件描述符足够
- worker_processes 设为 auto,让每个 CPU 核心跑一个 worker



















