非阻塞io是nginx高性能的核心机制,通过o_nonblock+epoll/kqueue事件驱动实现单worker处理数万连接,避免线程挂起与上下文切换,结合sendfile零拷贝、缓存优化及精细内存控制,支撑高并发低开销。

非阻塞 IO 是 Nginx 高性能的底层执行模型,它不靠堆线程、不靠轮询等待,而是让单个 worker 进程“同时盯住”数万个连接,在数据真正就绪时才介入处理,从而把 CPU、内存和系统调用资源用在刀刃上。
避免进程空转与上下文切换
传统阻塞模式下,每个连接需独占一个线程或进程;一旦 read() 没有数据,进程就被挂起,但栈空间(几 MB)、文件描述符和调度权重仍在占用。Nginx 设置 socket 为 O_NONBLOCK 后,recv() 和 send() 立即返回 EAGAIN/EWOULDBLOCK,绝不等待。worker 进程立刻转向其他就绪事件,全程无挂起、无忙等、无频繁切换。8 核服务器配 8 个 worker,每个处理 10240 连接,理论支撑超 8 万并发,而内存仅消耗在连接结构体和请求池上。
依赖高效事件驱动机制
非阻塞本身只是“不卡住”,真正释放并发能力的是它与 epoll(Linux)或 kqueue(BSD)的深度绑定:
- 所有监听 socket 和已建立连接都注册进 epoll 实例,一次 epoll_wait() 可批量获取几十甚至上百个就绪 fd
- worker 按顺序逐个处理,解析请求头、读文件、转发后端、组装响应——每个环节都不阻塞
- 哪怕某个请求要等 upstream 响应,Nginx 也只将其挂起并重新加入 epoll 监听,不中断其他连接调度
降低系统调用与内核开销
非阻塞 + 事件驱动天然减少无效系统调用:
- sendfile() 零拷贝:小文件静态响应跳过用户态缓冲,一次系统调用完成磁盘到 socket 的传输
- open_file_cache 缓存 stat()/open() 结果,将高频元数据查询从每次请求降为分钟级
- tcp_nopush 与 tcp_nodelay 协同:前者合并 sendfile 数据填满 TCP 报文段,后者禁用 Nagle 算法,避免小响应包延迟
支撑精准内存控制与抗慢攻击能力
非阻塞必须配合严格的生命周期管理,否则高并发下易内存溢出:
- 每个连接只维护轻量级 ngx_connection_t 结构体,而非完整线程上下文
- client_header_buffer_size、proxy_buffer_size 等参数需按业务匹配:API 接口设 1k–8k,WebSocket 握手无需大缓冲,反向代理则建议 proxy_buffer_size ≥12k、proxy_buffers 8 16k
- 分级超时控制(client_header_timeout、send_timeout、proxy_read_timeout)防止某类慢请求长期占位











