Nginx通过“不等、不占、不卡”三原则实现高性能:强制非阻塞socket,结合epoll事件驱动,将请求拆解为异步状态机,并以超时和连接数限制兜底。

Nginx 通过“不等、不占、不卡”三原则,彻底绕开阻塞型系统调用的停顿问题:它从不等待数据就绪,也不为等待分配资源,更不让单个慢操作拖住整个工作进程。
所有 socket 强制设为非阻塞模式
Nginx 在 accept 新连接后,立刻对 socket 调用 fcntl(fd, F_SETFL, O_NONBLOCK)。这意味着:
- 调用
recv()时,若接收缓冲区为空,不挂起进程,而是立即返回EAGAIN或EWOULDBLOCK - 调用
send()时,若发送缓冲区已满,同样立即返回错误,而非等待 TCP 窗口腾出空间 - worker 进程拿到这个返回值后,直接跳转到事件循环的下一个就绪任务,CPU 时间不会被空耗在等待上
只在内核通知就绪时才真正操作 I/O
非阻塞本身不是解药,必须与操作系统事件机制协同:
- Linux 下使用
epoll,把成千上万个 socket 统一注册进监听表,由内核负责监控状态变化 - 仅当某个 socket 触发
EPOLLIN(可读)或EPOLLOUT(可写)事件时,Nginx 才对该 fd 执行一次非阻塞recv或send - 没有轮询、没有试探、没有忙等待——内核主动“叫醒”,Nginx 才动手,避免了 CPU 空转
请求处理被拆解为轻量异步状态机
一个 HTTP 请求不再是一条线性执行路径,而是多个可中断、可挂起的状态节点:
- TCP 连接建立后,注册读事件;收到部分 header 却暂停发送,就继续监听该 socket 的
EPOLLIN,不影响其他连接 - 转发请求给 upstream 时,当前连接状态转入 “waiting for upstream”,事件循环照常调度其余就绪 fd
- 后端响应到达,触发读事件;向客户端发送响应时若
send()返回EAGAIN,则注册EPOLLOUT,等可写再续发,不阻塞后续逻辑
超时与资源限制兜底,防止“假就绪”长期滞留
非阻塞 + 事件驱动确保“不被拖住”,但还需约束防止堆积:
-
client_header_timeout 10;和client_body_timeout 10;防 Slowloris 类攻击,慢发请求头/体超时即断连 -
send_timeout 60;控制两次write之间的最大间隔,避免低速下载长期占用连接 -
keepalive_timeout 75;主动回收空闲长连接,reset_timedout_connection on;用 RST 快速释放内核连接状态 -
worker_connections 65536;设硬上限,配合系统ulimit -n,防止 epoll 监听列表溢出


















