Nginx 高并发依赖 epoll(Linux)和 kqueue(BSD/macOS)事件模型适配:epoll 以 ET 模式、O(1) 就绪通知支撑 10 万+ 连接;kqueue 统一事件抽象但 macOS 受限于内核与资源限制,生产环境宜选 Linux。

Nginx 在高并发场景下能高效处理大量连接,关键在于它对不同操作系统底层 I/O 多路复用机制的适配。Linux 使用 epoll,而 FreeBSD、macOS 等系统使用 kqueue。两者都是事件驱动模型的核心,但设计思路和适用场景略有差异。
epoll:Linux 下高并发连接的主力引擎
epoll 是 Linux 2.6+ 内核提供的高性能 I/O 事件通知机制,专为解决传统 select/poll 在海量连接下的性能瓶颈而生。Nginx 默认启用 epoll(自动检测),无需额外配置即可发挥优势。
-
边缘触发(ET)模式:Nginx 默认使用 ET 模式,配合非阻塞 socket,减少重复事件通知,提升吞吐;需确保一次性读完数据或设置
recv()循环直到返回EAGAIN。 - 就绪列表无遍历开销:epoll 不像 select 需要轮询所有 fd,而是由内核维护就绪队列,Nginx 直接获取活跃连接,时间复杂度接近 O(1)。
-
单进程可支撑 10 万+ 连接:在合理调优(如增大
fs.file-max、net.core.somaxconn、ulimit -n)前提下,单 worker 进程常可稳定处理数万并发长连接(如 WebSocket、HTTP/2 流)。
kqueue:BSD 系统上更通用的事件接口
kqueue 是 FreeBSD 引入、后被 macOS 和其他 BSD 衍生系统采用的事件通知框架。相比 epoll,它支持更多事件类型(如文件变更、子进程状态、定时器),对 Nginx 而言,其网络事件处理能力同样优秀。
- 统一事件抽象:kqueue 将 socket、管道、信号甚至文件监控统一为 kevent,Nginx 只需一套逻辑适配多种资源,代码更简洁。
- 支持水平触发(LT)与边缘触发(EV_CLEAR):Nginx 主要使用 EV_CLEAR(类似 ET),每次读取后自动清除事件,避免重复触发;也可通过 flags 控制行为。
-
在 macOS 上表现稳健但有局限:虽然 kqueue 功能强大,但 macOS 对连接数限制较严(默认
kern.maxfiles较低),且 TCP 栈优化不如 Linux,实测极限并发通常略低于同配置 Linux + epoll。
实际选型不靠“切换”,而靠“匹配”
Nginx 启动时会自动选择当前系统最优的事件模型,用户一般无需手动指定。但理解差异有助于排查问题和调优:
- Linux 环境下不要强行改用
poll或select,它们无法支撑大规模连接; - FreeBSD 服务器建议保持
kqueue,并调大kern.maxfiles和net.inet.ip.portrange.*; - macOS 仅适合开发测试,生产环境避免用于高并发网关,因内核网络栈和资源限制较明显;
- 若日志中出现
nginx: [warn] kqueue change event error,多因文件描述符耗尽或 kevent 注册失败,应检查 ulimit 和系统级限制。
连接规模不止看事件模型
epoll/kqueue 是基础,但真正决定并发上限的是整体协同:
-
worker 进程数:设为 CPU 核心数(
worker_processes auto),避免锁争用; -
每个 worker 的连接上限:由
worker_connections控制,需与系统ulimit -n匹配; -
TIME_WAIT 处理:Linux 可开启
net.ipv4.tcp_tw_reuse加速端口回收;FreeBSD 对net.inet.tcp.msl和net.inet.tcp.fast_finwait2_recycle调优更有效; -
内存与缓冲区:过大的
client_body_buffer_size或未关闭tcp_nodelay可能在高连接下放大内存压力。


















