nginx高并发靠异步非阻塞i/o与事件驱动,单worker通过epoll/kqueue高效管理万级连接,全程零阻塞、零轮询、少内存拷贝。

Nginx 的高并发能力不是靠堆线程或进程,而是靠把“等待”这件事彻底去掉——它不等数据来,只在数据真正就绪时才动手。
单 worker 轮询万级连接,靠的是 epoll/kqueue
Linux 下 Nginx 默认用 epoll,FreeBSD/macOS 用 kqueue。这些机制让一个 worker 进程能同时监听数万个 socket,内核一旦发现某个连接有数据可读、可写或出错,立刻通知 Nginx,而不是让它一个个轮询检查。
- epoll 时间复杂度接近 O(1),十万连接下响应延迟几乎不变
- worker 不会因 recv() 没数据就卡住,遇到 EAGAIN 就切到下一个就绪事件
- 配置中显式写 use epoll; 可确保启用(虽多数版本已自动选择)
全程非阻塞,每个环节都不挂起
从 accept 新连接开始,到 send 响应结束,所有 socket 操作都设为 non-blocking。Nginx 把一次 HTTP 请求拆成多个状态阶段:读头、收体、转发、收响应、写回……每个阶段只做当前能做的那部分,其余挂起并注册对应事件,等下次就绪再继续。
- accept() 一次尽可能收完已排队的连接,减少事件循环空转
- send() 只发缓冲区允许的字节数,剩余数据留在 output buffer,等 write event 再续传
- 超时控制由红黑树统一管理,无需额外线程轮询
减少搬运和切换,让 CPU 真正干活
异步驱动的价值不仅在于“不等”,更在于“少动”。Nginx 尽量绕过用户态内存拷贝,避免频繁分配释放,把系统资源留给实际业务处理。
- 静态文件用 sendfile on;,内核直接从磁盘送进 socket 缓冲区
- HTTP 解析与响应组装复用 slab 内存池,避免 malloc/free 开销
- 关闭 access_log 或启用 buffered_logs,防止日志写入拖慢事件循环
配置得当,异步才能真正跑起来
再精巧的架构,配错了也会打折。关键配置不是孤立存在,而是一组协同动作:
- worker_processes auto; —— 让进程数匹配 CPU 核心,避免争抢
- worker_connections 65535; —— 配合 ulimit -n 调大系统文件描述符上限
- multi_accept on; —— 允许单次事件触发中批量 accept,应对突发流量
- keepalive_timeout 60; 和 proxy_http_version 1.1; —— 复用连接,减少握手开销











