非阻塞 i/o 是 nginx 高性能的核心机制——通过 o_nonblock + epoll 实现单进程处理数万连接,避免阻塞等待、线程切换与资源浪费,结合缓冲、超时和内核事件通知,保障高并发下稳定低延迟响应。

非阻塞 I/O 是 Nginx 实现极高响应能力的底层支柱——它不靠让单次操作变快,而是让整个系统“不空等、不错过、不卡住”,把有限 CPU 和内存真正用在处理就绪请求上。
让每个 worker 进程始终处于活跃调度状态
传统阻塞模型中,一次 recv() 若无数据,进程就会挂起,交出 CPU;而 Nginx 在 socket 上设置 O_NONBLOCK 后,读写操作立即返回:有数据就读取,没数据就收到 EAGAIN 错误,随即转向下一个就绪连接。整个 worker 进程从不因等待网络数据而停摆。
- 一个 4 核服务器开启 4 个 worker,每个处理 2 万连接,CPU 利用率反而更平稳,避免了高负载下的抖动和调度饥饿
- 突发流量涌入时,连接不会堆积在队列里排队等线程,而是由 epoll 快速分发到空闲 worker,毫秒级捕获并响应
- 即使某请求需等待后端 5 秒,该连接被挂起,其余上万个连接仍照常流转,不被拖累
消除线程切换与资源浪费,释放硬件真实算力
非阻塞 I/O 与事件驱动结合,彻底绕开了“一个连接一个线程”的资源陷阱。每个连接仅占用 KB 级内存(ngx_connection_t 结构体),无需栈空间、不触发上下文切换,CPU 时间片几乎全用于解析 header、转发请求、组装响应等有效工作。
- 对比 Apache prefork 模式:1 万连接 ≈ 1 万进程,内存暴涨、调度开销巨大;Nginx 同样连接数下,内存占用稳定可控
- 系统调用密度大幅降低:epoll_wait() 批量获取就绪事件,避免了轮询式 read()/write() 反复试探
- 文件描述符成为新瓶颈点,而非线程数上限,说明资源利用已逼近系统物理极限
配合缓冲与超时机制,守住响应确定性底线
非阻塞本身只是“不阻塞”,真正保障响应能力的是它与缓冲策略、分级超时的协同:读缓冲按需扩容但设硬限,大请求体自动落盘;client_header_timeout、send_timeout 等独立控制各阶段耗时,防止单一慢环节无限占位。
- client_header_buffer_size 设为 1k~4k,large_client_header_buffers 配置为 4 8k,兼顾 JWT 头体积与内存碎片风险
- keepalive_timeout 不宜过短(如低于 10s),否则连接频繁重建,抵消非阻塞带来的复用优势
- 关闭 access_log 或异步写入,在 QPS 过万场景下可直接削减磁盘 I/O 延迟,提升首字节时间(TTFB)
让内核通知代替用户态忙等,实现精准响应时机
Nginx 不是靠不断重试来“查”数据是否就绪,而是把所有 socket 注册进 epoll/kqueue,由内核在数据到达或缓冲区可写时主动通知。这种“内核喊你干活”的模式,确保每次系统调用都有明确产出,零空转、零盲等。
- multi_accept on 允许单次 epoll_wait() 接收多个新连接,减少系统调用次数
- tcp_nodelay on 减少小包延迟(如 API 响应),对 HTTP/1.1 小响应体尤为关键
- sendfile on 启用零拷贝,静态文件响应跳过用户态内存搬运,一次系统调用完成内核态直传











