Nginx 事件模块
概述
Nginx 是以事件的触发来驱动的,事件驱动模型主要包括事件收集、事件发送、事件处理(即事件管理)三部分。在Nginx 的工作进程中主要关注的事件是IO 网络事件 和 定时器事件。在生成的 objs 目录文件中,其中ngx_modules.c 文件的内容是Nginx 各种模块的执行顺序,我们可以从该文件的内容中看到事件模块的执行顺序为以下所示:注意:由于是在Linux 系统下,所以支持具体的 epoll 事件模块,接下来的文章结构按照以下顺序来写。
extern ngx_module_t ngx_events_module;
extern ngx_module_t ngx_event_core_module;
extern ngx_module_t ngx_epoll_module;
事件模块接口
ngx_event_module_t 结构体
在 Nginx 中,结构体 ngx_module_t 是 Nginx 模块最基本的接口。对于每一种不同类型的模块,都有一个具体的结构体来描述这一类模块的通用接口,该接口由ngx_module_t 中的成员ctx 管理。在 Nginx 中定义了事件模块的通用接口ngx_event_module_t 结构体,该结构体定义在文件src/event/ngx_event.h 中:
typedef struct {
ngx_str_t *name;
void *(*create_conf)(ngx_cycle_t *cycle);
char *(*init_conf)(ngx_cycle_t *cycle, void *conf);
ngx_event_actions_t actions;
} ngx_event_module_t;
在 ngx_event_module_t 结构体中actions 的类型是ngx_event_actions_t 结构体,该成员结构实现了事件驱动模块的具体方法。该结构体定义在文件src/event/ngx_event.h 中:
ngx_event_t 结构体
在 Nginx 中,每一个具体事件的定义由结构体ngx_event_t 来表示,该结构体ngx_event_t 用来保存具体事件。该结构体定义在文件 src/event/ngx_event.h 中:
在每个事件结构体 ngx_event_t 最重要的成员是handler 回调函数,该回调函数定义了当事件发生时的处理方法。该回调方法原型在文件src/core/ngx_core.h 中:
ngx_connection_t 结构体
当客户端向 Nginx 服务器发起连接请求时,此时若Nginx 服务器被动接收该连接,则相对Nginx 服务器来说称为被动连接,被动连接的表示由基本数据结构体ngx_connection_t 完成。该结构体定义在文件 src/core/ngx_connection.h 中:
在处理请求的过程中,若 Nginx 服务器主动向上游服务器建立连接,完成连接建立并与之进行通信,这种相对Nginx 服务器来说是一种主动连接,主动连接由结构体ngx_peer_connection_t 表示,但是该结构体 ngx_peer_connection_t 也是 ngx_connection_t 结构体的封装。该结构体定义在文件src/event/ngx_event_connect.h 中:
ngx_events_module 核心模块
ngx_events_module 核心模块的定义
ngx_events_module 模块是事件的核心模块,该模块的功能是:定义新的事件类型,并为每个事件模块定义通用接口ngx_event_module_t 结构体,管理事件模块生成的配置项结构体,并解析事件类配置项。首先,看下该模块在文件src/event/ngx_event.c 中的定义:
其中,模块的配置项指令结构 ngx_events_commands 决定了该模块的功能。配置项指令结构ngx_events_commands 在文件src/event/ngx_event.c 中定义如下:
从配置项结构体中可以知道,该模块只对 events{...} 配置块感兴趣,并定义了管理事件模块的方法ngx_events_block;ngx_events_block 方法在文件src/event/ngx_event.c 中定义:
另外,在 ngx_events_module 模块的定义中有一个成员ctx 指向了核心模块的通用接口结构。核心模块的通用接口结构体定义在文件src/core/ngx_conf_file.h 中:
因此,ngx_events_module 作为核心模块,必须定义核心模块的通用接口结构。ngx_events_module 模块的核心模块通用接口在文件src/event/ngx_event.c 中定义:
所有事件模块的配置项管理
Nginx 服务器在结构体 ngx_cycle_t 中定义了一个四级指针成员 conf_ctx,整个Nginx 模块都是使用该四级指针成员管理模块的配置项结构,以下events 模块为例对该四级指针成员进行简单的分析,如下图所示:
每个事件模块可以通过宏定义 ngx_event_get_conf 获取它在create_conf 中分配的结构体的指针;该宏中定义如下:
从上面的宏定义可以知道,每个事件模块获取自己在 create_conf 中分配的结构体的指针,只需在ngx_event_get_conf 传入参数ngx_cycle_t 中的 conf_ctx 成员,并且传入自己模块的名称即可获取自己分配的结构体指针。
ngx_event_core_module 事件模块
ngx_event_core_module 模块是一个事件类型的模块,它在所有事件模块中的顺序是第一,是其它事件类模块的基础。它主要完成以下任务:
创建连接池;
决定使用哪些事件驱动机制;
初始化将要使用的事件模块;
ngx_event_conf_t 结构体
ngx_event_conf_t 结构体是用来保存ngx_event_core_module 事件模块配置项参数的。该结构体在文件src/event/ngx_event.h 中定义:
ngx_event_core_module 事件模块的定义
该模块在文件 src/event/ngx_event.c 中定义:
其中,模块的配置项指令结构 ngx_event_core_commands 决定了该模块的功能。配置项指令结构 ngx_event_core_commands 在文件 src/event/ngx_event.c 中定义如下:
其中,每个事件模块都需要实现事件模块的通用接口结构 ngx_event_module_t,ngx_event_core_module 模块的上下文结构 ngx_event_core_module_ctx 并不真正的负责网络事件的驱动,所有不会实现ngx_event_module_t 结构体中的成员 actions 中的方法。上下文结构 ngx_event_core_module_ctx 在文件 src/event/ngx_event.c 中定义如下:
在模块定义中,实现了两种方法分别为 ngx_event_module_init 和ngx_event_process_init 方法。在Nginx 启动过程中没有使用 fork 出 worker 子进程之前,先调用 ngx_event_core_module 模块中的 ngx_event_module_init 方法,当fork 出 worker 子进程后,每一个 worker 子进程则会调用 ngx_event_process_init 方法。
ngx_event_module_init 方法在文件src/event/ngx_event.c 中定义:
ngx_event_process_init 方法在文件src/event/ngx_event.c 中定义:
参考资料:
《深入理解 Nginx 》
Last updated
Was this helpful?