Posts nginx 模块&配置解析详情
Post
Cancel

nginx 模块&配置解析详情

1. 基本结构说明

1.1 模块基本结构

ngx_module_s 是 Nginx 对模块元信息的统一描述结构。每个模块在编译期以一个全局 ngx_module_t 实例存在,Nginx 启动时遍历 ngx_modules[] 数组,根据该结构体完成模块识别、初始化及生命周期管理。模块本身并不在运行时主动注册,而是由核心代码按模块类型和顺序进行统一调度。

其中,index 表示模块在全局模块数组 ngx_modules[] 中的唯一编号;ctx_index 表示模块在同类型模块上下文数组中的位置,用于快速定位模块私有配置。ctxcommands 描述模块的配置解析与处理能力,type 决定模块所属子系统(如 CORE / EVENT / HTTP)以及其参与的处理流程。init_* / exit_* 回调定义了模块在 master / worker 等不同生命周期阶段的初始化与退出行为,其余 sparespare_hook 字段用于 ABI 兼容与扩展预留。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// 基本结构体
struct ngx_module_s {
    ngx_uint_t            ctx_index;      /* 模块在 ctx 数组中的索引,用于 conf_ctx 查找模块配置 模块在“自己类型的模块上下文数组”里的编号。 比如它是第几个 HTTP 模块、第几个 EVENT 模块。 */
    ngx_uint_t            index;          /* 模块在 ngx_modules[] 数组中的唯一编号 */

    ngx_uint_t            spare0;         /* 备用字段(保留未用) */
    ngx_uint_t            spare1;         /* 备用字段 */
    ngx_uint_t            spare2;         /* 备用字段 */
    ngx_uint_t            spare3;         /* 备用字段 */

    ngx_uint_t            version;        /* Nginx 模块版本号(用于二进制兼容检查) */

    void                 *ctx;            /* 模块上下文指针(模块专用数据/回调集合) */
    ngx_command_t        *commands;       /* 模块可用指令列表(解析 nginx.conf) */
    ngx_uint_t            type;           /* 模块类型(NGX_CORE_MODULE/NGX_HTTP_MODULE/NGX_HTTP_FILTER_MODULE 等) */

    ngx_int_t           (*init_master)(ngx_log_t *log);    /* master 进程初始化时调用 */
    ngx_int_t           (*init_module)(ngx_cycle_t *cycle);/* 模块全局初始化(cycle 层面) */

    ngx_int_t           (*init_process)(ngx_cycle_t *cycle); /* worker 进程初始化 */
    ngx_int_t           (*init_thread)(ngx_cycle_t *cycle);  /* 线程初始化(少用,多数情况下为空) */
    void                (*exit_thread)(ngx_cycle_t *cycle);  /* 线程退出回调 */
    void                (*exit_process)(ngx_cycle_t *cycle); /* worker 进程退出回调 */

    void                (*exit_master)(ngx_cycle_t *cycle);  /* master 进程退出回调 */

    uintptr_t             spare_hook0;    /* 备用 hook 字段 */
    uintptr_t             spare_hook1;
    uintptr_t             spare_hook2;
    uintptr_t             spare_hook3;
    uintptr_t             spare_hook4;
    uintptr_t             spare_hook5;
    uintptr_t             spare_hook6;
    uintptr_t             spare_hook7;
};

// 2. 模块定义 & 初始化
ngx_module_t ngx_http_hello_module = {
        NGX_MODULE_V1,                 // #define NGX_MODULE_V1          0, 0, 0, 0, 0, 0, 1
        &ngx_http_hello_module_ctx,    /* module context */
        ngx_http_hello_commands,       /* module directives */
        NGX_HTTP_MODULE,               /* module type */
        NULL,                          /* init master */
        NULL,                          /* init module */
        NULL,                          /* init process */
        NULL,                          /* init thread */
        NULL,                          /* exit thread */
        NULL,                          /* exit process */
        NULL,                          /* exit master */
        NGX_MODULE_V1_PADDING
};

1.2 模块上下文指针

ctx 是模块与具体子系统(CORE / EVENT / HTTP 等)交互的关键入口。它并不是一个固定类型,而是一个 void *,在不同模块类型下指向不同的上下文结构体。例如 HTTP 模块中,ctx 实际指向一个 ngx_http_module_t 结构,用于向 HTTP 核心注册配置创建、合并以及配置解析前后的回调函数。

对于 HTTP 模块而言,ngx_http_module_t 定义了三层配置(main / srv / loc)的创建与合并逻辑,并允许模块在配置解析前后插入自定义处理流程。Nginx 在解析 nginx.conf 时,会根据模块类型对 ctx 进行强制类型转换,并按既定时机调用其中的回调函数,从而完成模块配置对象的生命周期管理。

` void ctx; / 模块上下文指针(模块专用数据/回调集合) / &ngx_http_hello_module_ctx, / module context */`

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
typedef struct {
    ngx_int_t   (*preconfiguration)(ngx_conf_t *cf);
    ngx_int_t   (*postconfiguration)(ngx_conf_t *cf);

    void       *(*create_main_conf)(ngx_conf_t *cf);
    char       *(*init_main_conf)(ngx_conf_t *cf, void *conf);

    void       *(*create_srv_conf)(ngx_conf_t *cf);
    char       *(*merge_srv_conf)(ngx_conf_t *cf, void *prev, void *conf);

    void       *(*create_loc_conf)(ngx_conf_t *cf);
    char       *(*merge_loc_conf)(ngx_conf_t *cf, void *prev, void *conf);
} ngx_http_module_t;

// 模块上下文
static ngx_http_module_t ngx_http_hello_module_ctx = {
        NULL,                          /* preconfiguration */
        NULL,                          /* postconfiguration */
        NULL,                          /* create main configuration */
        NULL,                          /* init main configuration */
        NULL,                          /* create server configuration */
        NULL,                          /* merge server configuration */
        NULL,                          /* create location configuration */
        NULL                           /* merge location configuration */
};

1.3 Command 指针

commands 指向模块支持的配置指令表,用于在解析 nginx.conf 时将文本指令映射为模块行为。每个 ngx_command_t 描述一条指令的名称、适用作用域及解析方式,HTTP 核心在配置阶段遍历该表,根据指令出现的位置调用对应的 set 回调完成配置或注册处理逻辑。

对于 HTTP 模块而言,指令通常在 location / server / http 等上下文中生效,其解析过程完全由 ngx_command_t 表驱动,模块只需提供指令描述与回调函数即可,无需关心配置文件的遍历与调度细节。

ngx_http_hello_commands, /* module directives */ ngx_command_t *commands; /* 模块可用指令列表(解析 nginx.conf) */

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 定义指令(例如 hello)
static ngx_command_t ngx_http_hello_commands[] = {
        {
                ngx_string("hello"),
                NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
                ngx_http_hello,
                0,
                0,
                NULL
        },
        ngx_null_command
};

struct ngx_command_s {
    ngx_str_t             name;
    ngx_uint_t            type;
    char               *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
    ngx_uint_t            conf;
    ngx_uint_t            offset;
    void                 *post;
};

1.4 ngx_modules.c 的创建

This post is licensed under CC BY 4.0 by the author.

Contents

Trending Tags