nginx 高并发核心在于非阻塞 i/o 与事件驱动模型协同:单 worker 可管理数万连接,socket 设为 o_nonblock,配合 epoll/kqueue 实现就绪调度,请求被拆解为异步状态机,并通过 worker_connections、超时等参数防资源耗尽。

Nginx 实现极高并发连接处理,核心不是靠堆资源,而是靠非阻塞 I/O 与事件驱动模型深度协同——单个 worker 进程能同时管理数万连接,每个连接只在真正就绪时才被调度,其余时间完全不占 CPU、不抢调度、不消耗线程栈。
非阻塞 socket 是基础前提
所有客户端连接的 socket 都被设为 O_NONBLOCK 模式。这意味着:
- recv() 调用:有数据立刻读取;没数据直接返回 EAGAIN,绝不等待
- send() 调用:缓冲区有空间就发;满了也立刻返回 EAGAIN,不卡住当前逻辑
- 后续是否继续读或写,完全由内核事件机制(如 epoll)通知,Nginx 不主动轮询、不忙等
事件驱动模型接管就绪调度
Linux 下默认使用 epoll,FreeBSD/macOS 使用 kqueue。它们让 Nginx 能高效监听成千上万个 socket 的状态变化:
- 一次 epoll_wait() 可批量获取多个就绪事件(比如几十个连接同时发来请求头)
- 内核只在真正“可读”“可写”“断开”“超时”时才通知,避免传统 select/poll 的 O(n) 扫描开销
- worker 进程按顺序处理这些就绪事件,全程无阻塞、无上下文切换
连接生命周期被拆解为异步状态机
一个 HTTP 请求不再是一条线走到底,而是被切分成多个可挂起、可恢复的阶段:
- TCP 握手完成 → 触发 accept 事件,注册该 socket 的 EPOLLIN 监听
- 客户端慢发请求头 → 每次 read 返回 EAGAIN 后,连接仍保留在 epoll 中,继续监听 EPOLLIN
- 转发请求给后端(如 upstream)→ 当前连接挂起,worker 立即转向其他就绪连接
- 后端响应到达 → 触发读事件;尝试 send 响应 → 若又遇 EAGAIN,则注册 EPOLLOUT,等可写再续发
配套约束防止资源耗尽
非阻塞本身不能兜底,必须搭配合理限制才能稳定承载高并发:
- worker_connections 设为 65536 或更高,并同步调高系统 ulimit -n
- client_header_timeout 5s、client_body_timeout 10s,防 Slowloris 类攻击
- send_timeout 15s 控制响应发送间隔,避免弱网客户端长期占用连接
- keepalive_timeout 15–30s,及时释放空闲长连接,腾出 fd 槽位











