nginx连接建立采用异步非阻塞机制:先复用keepalive空闲连接,无可用时发起non-blocking connect并注册写事件,由epoll通知握手完成后再发送请求,全程不阻塞worker。

Nginx 的连接建立过程本身不阻塞,靠的是异步事件驱动机制把“等连接就绪”这件事变成可调度的事件,而不是让 worker 停下来干等。
连接建立不是一上来就发起的
客户端请求到达后,Nginx 并不会立刻向后端发起 TCP 连接。它先完成 upstream peer 选择(比如 round-robin)、构造代理请求头,但此时 u->peer.connection 仍是 NULL —— 物理连接还没动。真正建连被推迟到必须发送数据时才触发,由 ngx_http_upstream_connect 统一调度。
优先复用空闲 keepalive 连接
该函数第一件事是查 upstream 的 keepalive 连接池。只要池里有可用连接(且未超 idle 超时),就直接复用,跳过 TCP 握手。这大幅降低延迟和系统调用开销。
- 复用前提:proxy_http_version 1.1 + proxy_set_header Connection ''
- 若后端响应含 Connection: close,该连接读完响应后即关闭并从池中移除
- keepalive_requests 和 keepalive_timeout 控制单连接复用次数与空闲时长
新连接走非阻塞 connect + 事件监听
池中无可用连接时,调用 ngx_event_connect_peer 发起 connect()。Linux 下几乎总返回 EINPROGRESS,Nginx 把 socket 设为 non-blocking,并注册写事件 handler(ngx_http_upstream_connect_peer_handler)。
- epoll_wait 检测到该 socket 可写,说明三次握手完成
- handler 被触发,继续执行请求头发送等后续流程
- 整个过程不占用 worker 线程,同一 worker 可同时处理成百上千个待建连或已建连的请求
超时与失败自动兜底
connect 超时由 proxy_connect_timeout 控制,底层通过定时器绑定到该连接的 event 上。一旦超时或被拒,ngx_http_upstream_next 启动重试逻辑:标记当前 peer 不可用、尝试下一个 upstream 节点,或返回 502/504 错误。
- 失败不中断事件循环,worker 仍可响应其他请求
- 重试次数、失败判定策略可通过 upstream 指令精细控制











