Nginx支撑数万并发连接的关键在于非阻塞IO与事件驱动模型协同:socket设为O_NONBLOCK后,read/write立即返回EAGAIN,不阻塞进程;配合epoll/kqueue批量监听就绪事件,单worker可高效轮询处理数千连接,避免线程堆积和资源浪费。

Non-blocking IO 是 Nginx 能支撑数万并发连接的关键技术,它不靠堆线程或进程,而是让单个 worker 进程“一心多用”——在等待网络数据就绪时,立刻转去处理其他已就绪的连接。
为什么非阻塞比阻塞更省资源
传统阻塞 I/O(如早期 Apache 的 prefork 模式)中,每个连接独占一个进程或线程:调用 read() 时若数据还没到,进程就挂起,CPU 不再分配时间片,但内存和文件描述符仍被占用。1 万个空闲连接,就可能卡住 1 万个线程,消耗大量内存和上下文切换开销。
Non-blocking IO 则不同:
- socket 设置了 O_NONBLOCK 标志后,read() 和 write() 立即返回
- 有数据就读取;没数据就返回 EAGAIN 或 EWOULDBLOCK,不等待
- Nginx 不主动轮询,而是交给 epoll(Linux)或 kqueue(BSD)监听哪些 socket “可读”或“可写”
- 只在真正就绪时才触发回调,避免空转和忙等
事件驱动如何配合 Non-blocking IO
Non-blocking 本身只是“不卡住”,真正发挥高并发价值的是它与事件驱动模型的结合:
- worker 进程启动后,把所有监听 socket 和已建立连接的 fd 都注册进 epoll 实例
- 调用 epoll_wait() 一次可批量获取多个就绪事件(比如 50 个连接同时发来请求头)
- worker 按顺序逐个处理这些就绪事件:解析请求、读文件、转发给后端、组装响应……全程不阻塞
- 哪怕某个请求要等后端 PHP 响应,Nginx 也不会停在这儿,而是把它挂起,继续处理别的就绪连接
实际配置中要注意的几个关键点
默认情况下 Nginx 已启用非阻塞 I/O,但承载能力还取决于配套设置:
- worker_processes auto; —— 让 worker 数量匹配 CPU 核心数,避免过度竞争
- worker_connections 65535; —— 单个 worker 最大连接数,需确保系统 ulimit -n 足够(如设为 65536 或更高)
- use epoll;(Linux 下显式指定)—— 明确启用高效事件模型,比 select/poll 更适合高并发
- accept_mutex on; —— 多 worker 竞争新连接时减少惊群效应,提升稳定性
- 禁用 tcp_nodelay off;(即开启 Nagle 算法)—— 对 HTTP 小包不利,建议保持默认 on
它不是万能的,但解决了最核心的瓶颈
Non-blocking IO 主要优化的是网络 I/O 等待环节,对 CPU 密集型任务(如复杂 rewrite、SSL 握手、大文件压缩)帮助有限。此时需要配合:
- 启用 ssl_buffer_size 控制 TLS 分片大小
- 用 sendfile on; 避免内核态到用户态的数据拷贝(尤其静态文件)
- 对动态内容,合理设置 fastcgi_read_timeout 等超时,防止 worker 被长尾请求拖住


















