Nginx高效吞吐依赖非阻塞I/O、事件驱动多路复用和状态机驱动:socket设为O_NONBLOCK避免阻塞,epoll/kqueue实现O(1)就绪事件调度,ngx_connection_t按阶段推进连接处理,配合sendfile、tcp_nopush等机制提升整体吞吐。

Nginx 实现高效吞吐,靠的不是把单次读写变快,而是让一个 worker 进程“不闲着、不卡住、不浪费”——Non-blocking I/O 是这个逻辑的底层支点。
非阻塞 I/O 让每个 socket 都“随时可切”
Nginx 把所有连接套接字(socket)设为 O_NONBLOCK 模式。这意味着:
-
accept()、read()、write()等系统调用立刻返回,哪怕没数据、缓冲区满、连接还没建好 - 若无就绪数据,返回
EAGAIN或EWOULDBLOCK,而不是挂起进程 - 进程不等待,马上转向处理其他已就绪的连接
这就避免了传统阻塞模型里“一个慢连接拖死整个线程”的问题,也让 worker 始终处于活跃调度状态。
事件驱动 + 多路复用是调度中枢
Nginx 依赖 epoll(Linux)或 kqueue(BSD/macOS)这类内核机制:
- 所有 socket 统一注册进事件表,由内核维护“哪些 fd 已就绪”
-
epoll_wait()以 O(1) 时间复杂度批量返回就绪事件列表,无轮询开销 - worker 进入循环:等事件 → 取就绪列表 → 按连接当前状态分发处理函数 → 回头再等
哪怕有 10 万连接,只要其中 200 个此刻有数据到达,就只处理这 200 个;其余连接安静待在内核事件表里,不占 CPU、不耗栈、不触发上下文切换。
状态机驱动每个连接按需推进
每个连接不靠独立线程维持上下文,而是由一个轻量结构体 ngx_connection_t 记录当前阶段:
-
NGX_HTTP_READING_REQUEST(正在收请求头) -
NGX_HTTP_PROCESS_REQUEST(解析并准备响应) -
NGX_HTTP_SENDING_RESPONSE(往客户端发数据)
事件到来时,Nginx 查状态、走对应回调(如 ngx_http_process_request_line),只做该阶段该做的事,完成后自动转入下一状态。整个生命周期被拆解成可中断、可复用的小步操作。
配合关键机制放大吞吐收益
-
sendfile on:静态文件响应走内核零拷贝路径,省去用户态内存拷贝和两次系统调用 -
tcp_nopush on:攒够 TCP 最大报文段(MSS)再发,减少小包数量 -
worker_connections调高(如 10240),配合ulimit -n充分利用 fd 资源 -
client_*_timeout和send_timeout主动清理无进展连接,防慢连接长期占位
它不追求单连接最快,而追求单位时间完成最多“有效工作单元”——一次事件循环里,谁 ready 就处理谁,谁卡住就先放一放,整体节奏紧凑、资源干净、响应及时。









