非阻塞 I/O 是 Nginx 高并发负载均衡的底层支撑,通过 epoll/kqueue 异步监听数万 socket,配合 O_NONBLOCK、分级超时与资源限制,实现连接快速分发、挂起与复用,保障调度高效稳定。

非阻塞 I/O 是 Nginx 实现高并发负载均衡调度的底层支撑,它不直接决定“分给谁”,但确保“分得动、分得稳、分得快”——没有它,再多的 upstream 服务器也轮不到被调度。
让单个 worker 同时盯住成千上万个连接
负载均衡的前提是能同时维持大量客户端连接和上游连接。Nginx 每个 worker 进程通过 epoll(Linux)或 kqueue(BSD/macOS)一次性监听数万 socket 状态,所有 socket 均设为 O_NONBLOCK。这意味着:
- 接收新连接(accept)不会卡住,可一次处理多个新连入请求(multi_accept on)
- 读取客户端请求头/体时若数据未到齐,立刻返回 EAGAIN,连接挂起,worker 转去处理其他就绪事件
- 向 upstream 转发请求后,不等响应回来,而是把当前连接注册 EPOLLIN,继续处理下一个请求
请求分发阶段全程异步解耦
负载均衡不是“接完再转”,而是把整个转发链路拆成可中断、可挂起的事件阶段:
- TCP 握手完成 → 触发 accept 事件,分配连接结构体,注册读事件
- 收到部分请求头 → 解析 Host、URI,匹配 server/upstream 块,选定 upstream 组
- 与 upstream 建连或复用长连接 → 若 connect() 返回 EINPROGRESS,注册 EPOLLOUT 等就绪;若已就绪,立即发送请求
- 等待 upstream 响应 → 当前连接挂起,worker 不阻塞,去处理其他客户端或 upstream 的就绪事件
避免慢连接拖垮整体调度能力
非阻塞机制配合分级超时,防止个别异常请求阻塞调度流水线:
- client_header_timeout 控制客户端发请求头的最大等待时间,防 Slowloris
- proxy_connect_timeout / proxy_read_timeout 分别约束与 upstream 建连和读响应的耗时
- send_timeout 限制向客户端回传响应时两次 write 之间的间隔,避免因客户端网速慢长期占位
- 所有超时触发后,连接被干净关闭,fd 归还 epoll 监听池,不残留、不堆积
资源可控才能持续调度
非阻塞本身不设限,必须靠配置锚定资源边界,否则监听 fd 数量会突破系统上限:
- worker_connections 必须与 ulimit -n 设置一致,确保每个 worker 能注册足够多的 socket
- upstream 中配置 max_conns 和 queue,限制单台后端的最大并发连接数及排队长度
- 使用 least_conn 或 hash $request_uri 等算法时,非阻塞模型仍能保证决策后立即发起异步建连或复用,不因算法复杂度增加延迟


















