non-blocking io 不提升单次读写速度,但使 nginx 以少量 worker 进程管理数十万连接,显著提高吞吐量;通过事件驱动、缓冲区精细管理和系统级 fd 限制对齐,实现高并发、低开销、及时响应。

Non-blocking IO 本身不加快单次读写速度,但它让 Nginx 能用极轻量的方式同时管理数万甚至百万级连接,从而显著提升整体吞吐量。
避免线程资源浪费
传统阻塞模型为每个连接分配一个线程,线程在等待数据时处于休眠状态,内存和调度资源被长期占用。Nginx 在 Non-blocking 模式下只用少量 worker 进程(通常与 CPU 核心数一致),每个进程通过事件循环处理成千上万个连接——连接建立后仅维护一个轻量的 ngx_connection_t 结构体,不独占栈空间,也不触发线程切换。
- 无需为慢客户端(如低速上传)预留额外线程
- 系统线程数不再成为并发上限瓶颈(Linux 默认约 3 万线程,而 Nginx 可轻松支撑 10 万+ 连接)
- 内存开销更可控:连接数翻倍,内存增长远低于线性比例
事件驱动,响应更及时
Nginx 基于 epoll(Linux)或 kqueue(BSD)等高效事件机制,一旦 socket 准备就绪(可读/可写),内核立即通知事件循环,Nginx 在毫秒级完成回调调度,不依赖轮询或阻塞等待。
- 新连接接入、请求头到达、响应可发送等关键节点均被快速捕获
- 即使部分连接处于长空闲或慢传输状态,也不影响其他活跃连接的处理节奏
- 尤其适合高并发、短连接(如 API)或混合长短连接(如 Web + 文件下载)场景
缓冲区策略配合非阻塞行为
Non-blocking IO 的高效发挥,依赖 Nginx 对缓冲区的精细化管理:读取时不贪大,写入时不硬塞,全程按需、分阶段、及时释放。
- 读缓冲采用“试探性读取”:调用
recv()仅使用当前可用空间,返回EAGAIN就暂停,不阻塞也不空转 - 大请求体自动落盘(
client_body_temp_path),避免内存耗尽;小请求头复用固定缓冲区(client_header_buffer_size) - 写操作启用
sendfile on时由内核直接零拷贝传输静态文件;否则数据暂存 send buffer,待 socket 可写时再续发
系统级限制必须对齐
Non-blocking IO 的并发潜力,只有在底层资源不卡脖子时才能完全释放。常见瓶颈是文件描述符(FD)三层未打通:
- 系统全局上限:
/proc/sys/fs/file-max建议 ≥2000000(百万连接场景) - systemd 服务限制:
LimitNOFILE=1000000(写入 nginx.service) - Nginx 进程内限制:
worker_rlimit_nofile 1000000;+worker_connections 65535; - 用户级 ulimit:
/etc/security/limits.conf中设置 soft/hard nofile 至相同值
四者缺一不可,且需预留余量(例如 worker_connections × 2~3 倍)应对日志、上游连接等额外 FD 消耗。











