Posts 聊聊nginx 配置解析
Post
Cancel

聊聊nginx 配置解析

概览

Nginx 的配置解析机制设计得非常灵活,以便支持高度模块化和分层配置。本文将带你从源码角度梳理 Nginx 配置解析的全过程,包括核心模块配置、HTTP 模块分层配置以及最终的运行时优化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 断点配置
// 可看到每个关键字解析方式
3       breakpoint     keep y   0x000055555557a545 in ngx_conf_handler at src/core/ngx_conf_file.c:328

static ngx_int_t
ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last)
{
    ...
        for (i = 0; ngx_modules[i]; i++) {

            ...

            cmd = ngx_modules[i]->commands;
        }

1. 核心模块初始化(ngx_init_cycle

Nginx 启动时,首先需要为核心模块(NGX_CORE_MODULE)分配并初始化配置结构。核心模块包括日志模块、错误处理模块等,它们是 Nginx 能够运行的基础。

核心代码片段如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
for (i = 0; ngx_modules[i]; i++) {
    if (ngx_modules[i]->type != NGX_CORE_MODULE) {
        continue;
    }

    module = ngx_modules[i]->ctx;

    // 调用模块自己的 create_conf 方法创建配置结构
    if (module->create_conf) {
        rv = module->create_conf(cycle);
        if (rv == NULL) {
            ngx_destroy_pool(pool);
            return NULL;
        }

        // 将创建好的配置结构挂载到全局 conf_ctx 数组
        cycle->conf_ctx[ngx_modules[i]->index] = rv;
    }
}

解释:

  • ngx_modules[i]->type:判断模块类型,仅处理核心模块。
  • module->create_conf(cycle):调用模块自己提供的创建配置结构函数。
  • cycle->conf_ctx[ngx_modules[i]->index]:将模块配置结构存入全局数组,方便后续访问。

核心模块的配置结构通常比较简单,不涉及多层嵌套。


2. 配置解析主入口(ngx_conf_parse

核心模块配置初始化完成后,Nginx 会进入 配置解析阶段,读取 nginx.conf 文件并逐条处理指令:

1
2
3
4
5
if (ngx_conf_parse(&conf, &cycle->conf_file) != NGX_CONF_OK) {
    environ = senv;
    ngx_destroy_cycle_pools(&conf);
    return NULL;
}

ngx_conf_parse 是配置解析的入口,它会:

  1. 读取配置文件的每一行;
  2. 根据指令匹配对应的模块命令;
  3. 调用回调函数进行配置结构赋值。

3. 配置解析核心(ngx_conf_parsengx_conf_handler

配置解析的关键在于两步:

1
2
3
4
5
// 取出模块自己的配置结构
conf = ((void **) cf->ctx)[ngx_modules[i]->index];

// 执行指令回调,将值写入模块配置结构
rv = cmd->set(cf, cmd, conf);
  • 取结构体:从全局 conf_ctx 数组中找到模块自己的配置结构。
  • 赋值:调用模块命令对应的 set 回调函数,将指令的值写入配置结构中。

对于核心模块,这个配置结构就是一层,直接存储在 conf_ctx 数组中。


4. HTTP 模块的特殊处理(ngx_http_block

当解析器遇到 http {} 指令时,会调用 HTTP 模块专用的 block 处理函数:

1
ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);

HTTP 模块配置结构

HTTP 模块的配置结构更加复杂,分为多层:

层级说明
Mainmain_conf,全局 HTTP 配置
Serversrv_conf,每个 server 块配置
Locationloc_conf,每个 location 块配置

每个 HTTP 模块都会在 ngx_http_module_t 或自定义 ctx 中定义如下回调函数:

1
2
3
4
5
6
7
8
9
10
11
NULL,                        /* preconfiguration方法 */
ngx_http_myfilter_init,       /* postconfiguration方法 */

NULL,                        /* create_main_conf方法 */
NULL,                        /* init_main_conf方法 */

NULL,                        /* create_srv_conf方法 */
NULL,                        /* merge_srv_conf方法 */

ngx_http_myfilter_create_conf, /* create_loc_conf方法 */
ngx_http_myfilter_merge_conf   /* merge_loc_conf方法 */
  • create_*_conf:分配并初始化配置结构
  • merge_*_conf:将父层配置合并到子层
  • preconfiguration / postconfiguration:模块初始化时执行的钩子
  • init:用于进一步初始化

5. HTTP 配置的收尾处理

HTTP 模块在配置解析完成后,还需要进行 运行时数据结构初始化和优化

1
2
3
4
5
6
7
if (ngx_http_init_phase_handlers(cf, cmcf) != NGX_OK) {
    return NGX_CONF_ERROR;
}

if (ngx_http_optimize_servers(cf, cmcf, cmcf->ports) != NGX_OK) {
    return NGX_CONF_ERROR;
}

5.1 初始化阶段处理器(Phase Handlers)

  • 每个 HTTP 请求在 Nginx 内部分为多个阶段,例如:

    • post-read
    • server-rewrite
    • find-config
    • rewrite
    • pre-access
    • access
    • try-files / content
    • log
  • 模块可以注册对应阶段的处理函数。
  • ngx_http_init_phase_handlers() 遍历所有 server/location,将这些函数挂到对应阶段数组,便于请求处理时快速调用。

5.2 优化服务器/端口/域名查找

  • ngx_http_optimize_servers() 对所有 server 配置按端口、IP、域名排序,建立查找表。
  • 运行时 HTTP 请求到来时可以高效匹配到对应 server/location。
  • 这一步是配置解析后的“性能优化”,不改变原始配置内容。

6. 总结 Nginx 配置解析流程

  1. 核心模块初始化

    • ngx_init_cycle 遍历所有核心模块,调用 create_conf 为每个核心模块分配配置结构。
  2. 解析配置文件

    • ngx_conf_parse 按行解析指令,找到对应模块命令并调用 cmd->set 写入模块配置结构。
  3. HTTP / Event / Stream 模块处理

    • 遇到 http {} 等块时,调用对应 block 处理函数,如 ngx_http_block
    • 为每个模块分配多层配置结构(main/srv/loc),并调用模块回调函数。
  4. 运行时初始化和优化

    • ngx_http_init_phase_handlers():初始化请求阶段处理函数。
    • ngx_http_optimize_servers():优化 server/port/域名查找表。

通过以上流程,Nginx 实现了模块化、分层、灵活而高效的配置系统。

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

Contents

Trending Tags