事件模型

本章节介绍 Nginx 支持的各种事件模型。

事件模型列表

模型平台说明性能
epollLinux高效的事件通知方法最高
kqueueFreeBSD, macOS高效的事件通知方法最高
eventportSolaris 10事件端口
/dev/pollUnix轮询设备
select通用可移植但效率低
poll通用可移植但效率低

事件模型原理: 事件模型是 Nginx 处理 I/O 事件的核心机制。不同的事件模型有不同的实现方式和性能特点。Nginx 支持多种事件模型,以适应不同的操作系统平台。

事件模型详解

epoll

适用平台:Linux 2.6+

特点

  • 高性能的事件通知方法
  • 支持数百万并发连接
  • 只需要将文件描述符添加一次,后续只需要等待事件通知
  • 返回的是活跃的连接列表,不需要遍历所有连接
  • 使用红黑树存储所有监听的文件描述符,查找效率高
  • 支持边缘触发(Edge Triggered)和水平触发(Level Triggered)两种模式

工作原理

  • epoll_create:创建一个 epoll 实例,返回一个文件描述符
  • epoll_ctl:向 epoll 实例添加、修改或删除需要监听的文件描述符
  • epoll_wait:等待 I/O 事件的发生,返回发生事件的文件描述符列表

kqueue

适用平台:FreeBSD, macOS

特点

  • 高效的事件通知方法
  • 支持多种事件类型
  • 支持过滤器
  • 支持一次性监听多个文件描述符

工作原理

  • kqueue:创建一个 kqueue 实例
  • kevent:向 kqueue 实例添加、修改或删除需要监听的事件
  • kevent:等待事件的发生,返回发生的事件列表

eventport

适用平台:Solaris 10

特点

  • Solaris 平台的事件端口
  • 高效的事件通知方法

工作原理

  • port_create:创建一个事件端口
  • port_associate:将文件描述符与事件端口关联
  • port_get:等待事件的发生,返回发生的事件列表

/dev/poll

适用平台:Unix

特点

  • 基于设备的轮询方法
  • 支持大量并发连接
  • 性能优于 select 和 poll

工作原理

  • 打开 /dev/poll 设备
  • 将文件描述符写入 /dev/poll 设备
  • /dev/poll 设备读取发生事件的文件描述符列表

select

适用平台:通用

特点

  • 可移植但效率低
  • 有连接数限制(通常 1024)
  • 每次调用都需要将文件描述符从用户空间复制到内核空间
  • 每次调用都需要遍历所有文件描述符,查找发生事件的文件描述符

工作原理

  • select:监听文件描述符的可读、可写、异常事件
  • select:返回发生事件的文件描述符列表

poll

适用平台:通用

特点

  • 可移植但效率低
  • 无连接数限制
  • 每次调用都需要将文件描述符从用户空间复制到内核空间
  • 每次调用都需要遍历所有文件描述符,查找发生事件的文件描述符

工作原理

  • poll:监听文件描述符的可读、可写、异常事件
  • poll:返回发生事件的文件描述符列表

自动选择

Nginx 会自动选择最适合平台的事件模型。

自动选择原理: Nginx 在编译时会检测当前平台支持的事件模型,并在运行时自动选择最高效的事件模型。例如,在 Linux 上会自动选择 epoll,在 FreeBSD 上会自动选择 kqueue

手动指定

events {
    use epoll;
}

手动指定说明: 如果需要手动指定事件模型,可以在 events 块中使用 use 指令指定。

最佳实践

  1. 使用自动选择:Nginx 会自动选择最适合平台的事件模型
  2. 手动指定最高效的事件模型:如果需要手动指定,选择最高效的事件模型
  3. 测试事件模型:测试不同事件模型的性能,选择最高效的事件模型
  4. 监控事件模型:监控事件模型的性能,及时发现异常