Nginx通过单线程事件循环+非阻塞I/O+多路复用实现高并发,每个worker进程监听海量socket,内核就绪后触发回调,避免阻塞、上下文切换与锁竞争,内存占用低。

Nginx 用单线程事件循环(event loop)替代多线程模型,核心是避免频繁创建/销毁线程、减少上下文切换和锁竞争,从而在高并发下保持低内存占用与高吞吐。
事件循环如何接管网络 I/O
传统多线程服务器为每个连接分配一个线程,遇到 read/write 等系统调用时线程阻塞,CPU 空转等待内核就绪。Nginx 则基于 epoll(Linux)、kqueue(BSD)等异步 I/O 多路复用机制,让单个 worker 进程同时监听成千上万个 socket。它不主动读写,而是注册事件(如“fd 可读”),由内核在数据到达时通知,再统一调度回调处理——I/O 不再阻塞执行流。
worker 进程 + 非阻塞 I/O + 事件驱动
- 每个 worker 是独立的单线程进程(非线程),通过 非阻塞 socket 发起 accept、recv、send 等调用;失败时立即返回(如 EAGAIN/EWOULDBLOCK),而非等待
- 所有 I/O 操作都嵌入事件循环主循环中:检查就绪事件 → 分发处理 → 返回循环开头,持续轮询
- 请求生命周期被拆解为多个事件阶段(如接收 header、读 body、转发 upstream、写响应),每阶段只做少量工作,立刻交还控制权
规避多线程典型弊端的具体体现
- 无上下文切换开销:10 万并发连接 ≈ 10 万文件描述符,但仅需 4–8 个 worker 进程,远少于线程数,避免 CPU 频繁切换栈和寄存器
- 无锁设计主导:worker 进程间无共享连接状态,各自管理自己的连接和内存池;跨进程通信(如共享内存计数)才用轻量锁,业务路径几乎无锁
- 内存可控:每个连接只分配 KB 级内存(buffer + 上下文结构),不为每个连接预留栈空间(线程默认栈常为 1–8MB)
- 无惊群与唤醒震荡:epoll 使用 ET 模式 + 单 worker 接收新连接(accept_mutex),避免多进程争抢同一事件
注意:事件循环不等于完全无阻塞
若配置了阻塞式模块(如某些第三方 Lua 脚本未设超时)、或上游服务响应慢且未启用异步代理(proxy_buffering off + proxy_http_version 1.1),worker 仍可能在某个阶段等待。真正发挥优势的前提是:全链路使用非阻塞 I/O,并合理设置超时(proxy_read_timeout、client_header_timeout 等)。










