Nginx 通过非阻塞 I/O、epoll/kqueue 事件驱动及合理超时与缓冲配置,实现高并发连接处理与小文件高效传输。

Nginx 用非阻塞 I/O 提升请求速率,核心不是“让单次读写更快”,而是让有限资源服务更多连接、减少等待空转、避免线程/进程卡死。它不靠硬件加速,而靠事件驱动调度和系统调用协同优化,把 CPU 和内存真正用在处理就绪任务上。
非阻塞 socket + epoll/kqueue 是性能基础
Linux 下 Nginx 默认启用 epoll,FreeBSD/macOS 用 kqueue——这些内核机制能高效监听成千上万个 socket 的状态变化。关键前提是 socket 必须设为非阻塞模式:
- 调用 recv() 时若无数据,立刻返回 EAGAIN/EWOULDBLOCK,而不是挂起进程
- 调用 send() 时若 TCP 窗口满,同样立即返回错误,Nginx 转去处理其他连接
- 所有连接共用少量 worker 进程,每个进程轮询 epoll 返回的就绪事件列表,只处理“此刻能读或能写的那些”
慢连接不拖垮整体吞吐
传统阻塞服务器(如 Apache prefork)面对慢速客户端会锁住整个线程;Nginx 不会。1000 个缓慢上传 Body 的连接,在 Nginx 中只是 epoll 监听表里的 1000 个 fd:
- 它们长期处于“等待可读”状态,不消耗 CPU,也不抢占调度时间片
- 只要其中任意一个就绪(比如某客户端终于发完 header),事件循环马上响应
- 其余连接继续等待,不影响新请求接入和已有快连接的响应
配合超时与缓冲区才真正防住瓶颈
非阻塞本身不能无限兜底,必须搭配合理配置防止资源耗尽:
- client_header_timeout 和 client_body_timeout:限制客户端发请求头/体的最大时间,防 Slowloris 类攻击
- send_timeout:控制两次 send() 之间的最大间隔,避免因客户端接收慢长期占连接
- proxy_buffer_size 和 proxy_buffers:合理设置上游响应缓存大小,避免频繁 read/write 切换影响代理效率
- worker_connections 需匹配系统 ulimit -n,确保 epoll 能监控足够多文件描述符
小文件场景下进一步释放 I/O 效率
对 CSS、JS、图标等高频小文件,Nginx 还叠加了零拷贝与元数据缓存策略:
- 启用 sendfile on + tcp_nopush on,跳过用户态缓冲,由内核直接从 page cache 拷到 socket 发送队列
- 开启 open_file_cache 缓存 stat/open 结果,大幅降低高频访问下的系统调用开销
- 关闭不必要的 access_log,避免每次请求都触发日志写入 I/O
- 用前缀匹配(location /static/)替代正则,减少路径解析 CPU 消耗


















