1、nginx使用conf配置

2、nginx模块开发 hander ,filter,upstream

3、nginx源码 多线程网络,http状态机,多进程网络加锁

4、nginx基础组件、线程池、内存池、原子、共享内存,string,list,hash,array

二、步骤

5、解压四个文件

6、配置文件

yang@ubuntu:~/sambashare/4.5.1nginx/Nginx/nginx-1.22.1 ./configure --prefix=/usr/local/nginx --with-http_realip_module --with-http_addition_module --with-http_ssl_module --with-http_gzip_static_module --with-http_secure_link_module --with-http_stub_status_module --with-stream --with-pcre=/home/yang/sambashare/4.5.1nginx/Nginx/pcre-8.45 --with-zlib=/home/yang/sambashare/4.5.1nginx/Nginx/zlib-1.2.13 --with-openssl=/home/yang/sambashare/4.5.1nginx/Nginx/openssl-1.1.1s

7、make

8、sudo make install

9、yang@ubuntu:~/sambashare/4.5.1nginx/Nginx/nginx-1.22.1$ cd /usr/local/nginx/

10、yang@ubuntu:/usr/local/nginx$ sudo ./sbin/nginx  -c conf/nginx.conf 运行

11、yang@ubuntu:/usr/local/nginx$ sudo ./sbin/nginx  -reload conf/nginx.conf

12、yang@ubuntu:/usr/local/nginx$ sudo ./sbin/nginx  -s conf/nginx.conf

king.conf

./sbin/nginx -? 如下所示

命令 作用
-h-? 显示帮助信息
-v 显示 Nginx 版本号
-V 显示版本号 + 编译参数(非常重要!可查看是否启用了某模块)
-t 测试配置文件语法是否正确(不启动服务)
-T 测试配置并打印所有加载的配置内容(调试神器)
-c file 指定配置文件路径(默认是 conf/nginx.conf
例:./sbin/nginx -c /my/custom.conf
-p prefix 设置前缀路径(即 --prefix 的运行时覆盖)
例:./sbin/nginx -p /home/user/mynginx/
-g directives 设置全局配置指令(临时覆盖)
例:./sbin/nginx -g "worker_processes 2;"

一、Nginx 配置文件片段,详细分析:


✅ 配置内容


🔍 逐行解析

1. worker_processes 4;

  • 设置 Nginx 启动 4 个工作进程(worker process)
  • 每个进程独立运行,可以并行处理请求。
  • 建议设置为 CPU 核心数(或略多),这里可能是 4 核 CPU。

✅ 推荐:worker_processes auto; 可自动识别核心数。


2. events { ... }

  • 定义事件模型参数,影响并发性能。
worker_connections 1024;
  • 每个工作进程最多可同时处理 1024 个连接
  • 总最大并发连接数 = worker_processes × worker_connections
    → 这里是 4 × 1024 = 4096 个并发连接。

💡 注意:这只是一个上限,实际性能还受系统资源、网络、后端服务等影响。


3. http { ... }

  • HTTP 模块配置块,包含所有虚拟主机(server)的定义。

4. 四个 server

每个 server 块监听一个不同的端口:

端口 作用
listen 8000; 监听 8000 端口
listen 8001; 监听 8001 端口
listen 8002; 监听 8002 端口
listen 8003; 监听 8003 端口

出现的问题

1、无法进入 /home/yang 目录 → 无法访问里面的文件 → 403 Forbidden

✅ 方案:给 /home/yang 添加 others 的执行权限(最快,适合测试环境)
1chmod o+x /home/yang

执行后权限变为 drwxr-x--x(751)或 drwxr-xr-x(755)

这样 others 就能“进入”该目录(x 权限),进而访问子目录中的文件(前提是子目录也开放权限)。

✅ 验证:

1ls -ld /home/yang
2# 应显示 drwxr-x--x 或 drwxr-xr-x

然后重载 Nginx(其实不用重载,权限改完立即生效):

1curl http://192.168.198.135:9003

4.5.2 Nginx过滤器模块实现

1、组件如何使用

2、过滤器模块实现

组件

代码编译/home/yang/sambashare/4.5.1nginx/zip/ngx_str代码

4.5.3 

./configure --prefix=/usr/local/nginx --with-http_realip_module --with-http_addition_module --with-http_ssl_module --with-http_gzip_static_module --with-http_secure_link_module --with-http_stub_status_module --with-stream --with-pcre=/home/yang/sambashare/4.5.1nginx/Nginx/pcre-8.45 --with-zlib=/home/yang/sambashare/4.5.1nginx/Nginx/zlib-1.2.13 --with-openssl=/home/yang/sambashare/4.5.1nginx/Nginx/openssl-1.1.1s --add-module=/home/yang/sambashare/4.5.1nginx/ngx_code_test_/ngx_http_voice_filter_module

config文件

二、struct ngx_command_s 结构体

struct ngx_command_sNginx 配置系统的核心数据结构之一,用于描述一个配置指令(directive)的元信息。每一个 Nginx 模块若想在配置文件中提供可配置项(如 gzip on;worker_processes 4;),就必须定义一个或多个 ngx_command_t(即 ngx_command_s 的 typedef)类型的结构体。

下面逐字段详细解释其含义和作用:


📌 结构体定义(带注释)

struct ngx_command_s {
    ngx_str_t             name;        // 指令名称(如 "gzip", "listen")
    ngx_uint_t            type;        // 指令类型标志(上下文、参数个数、是否为块等)
    char               *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
                                    // 指令解析函数(核心!)
    ngx_uint_t            conf;        // 指定该指令作用于哪类配置结构体(main/srv/loc)
    ngx_uint_t            offset;      // 该指令值在配置结构体中的偏移量(字节)
    void                 *post;        // 后处理回调(可选,用于校验或触发逻辑)
};

💡 在 Nginx 源码中通常使用 typedef struct ngx_command_s ngx_command_t;,所以你常看到的是 ngx_command_t


🔍 字段详解

1. ngx_str_t name

  • 作用:指令的名称字符串。
  • 示例
    ngx_string("gzip"),          // 对应配置:gzip on;
    ngx_string("worker_processes")
    
  • 注意:必须用 ngx_string() 宏初始化,它会自动设置 .len.data

2. ngx_uint_t type

  • 作用复合标志位,描述指令的使用规则,包括:
    • 指令可用的上下文(main / http / server / location 等)
    • 指令接受的参数个数
    • 是否是块指令(如 http { ... }
    • 指令的数据类型(flag、num、string、take1~7 等)
常见标志组合(按位或 |):
标志 含义
NGX_MAIN_CONF 可在 main 上下文使用(如 worker_processes
NGX_HTTP_MAIN_CONF 可在 http{} 块内使用
NGX_HTTP_SRV_CONF 可在 server{} 块内使用
NGX_HTTP_LOC_CONF 可在 location{} 块内使用
NGX_CONF_FLAG 参数必须是 onoff
NGX_CONF_TAKE1 必须且只能有 1 个参数(如 root /var/www;
NGX_CONF_TAKE2 必须有 2 个参数(如 proxy_pass http://backend;
NGX_CONF_NOARGS 无参数(如 daemon off; 实际有参数,此例不恰当;更好的例子是某些开关)
NGX_CONF_1MORE 至少 1 个参数
NGX_CONF_2MORE 至少 2 个参数
NGX_CONF_BLOCK 是一个块指令(如 http, server
NGX_CONF_ANY 任意参数个数

✅ 示例:

NGX_HTTP_LOC_CONF | NGX_CONF_FLAG
// 表示:该指令可在 location 块中使用,且值为 on/off

3. char *(*set)(...)

  • 作用指令解析回调函数,当 Nginx 解析到该指令时,会调用此函数。
  • 函数签名
    char *set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
    
    • cf:当前配置上下文(含参数、日志、文件名行号等)
    • cmd:指向当前 ngx_command_t 自身
    • conf:指向当前上下文对应的配置结构体(如 location 配置)
  • 返回值
    • 成功:返回 NULL(通常用 NGX_CONF_OK 表示)
    • 失败:返回错误信息字符串(如 "invalid value")或 NGX_CONF_ERROR
常用内置 set 函数:
函数 用途
ngx_conf_set_flag_slot 解析 on/off → 存入 ngx_flag_t 字段
ngx_conf_set_num_slot 解析数字 → 存入 ngx_int_t
ngx_conf_set_size_slot 解析带单位的大小(如 1k, 2m
ngx_conf_set_str_slot 解析字符串 → 存入 ngx_str_t
ngx_http_upstream_server 解析 upstream 中的 server 指令

✅ 开发者也可以自定义 set 函数以实现复杂逻辑。


4. ngx_uint_t conf

  • 作用:指定该指令影响哪一类配置结构体
  • 常用值
    含义
    NGX_HTTP_MAIN_CONF_OFFSET 主配置(http 块外)
    NGX_HTTP_SRV_CONF_OFFSET server 块配置
    NGX_HTTP_LOC_CONF_OFFSET location 块配置
    NGX_HTTP_UPS_CONF_OFFSET upstream 块配置

💡 这个字段告诉 Nginx:当解析到该指令时,应该把值写入哪个层级的配置结构体中。


5. ngx_uint_t offset

  • 作用目标字段在配置结构体中的字节偏移量
  • 如何获取?使用 C 标准宏 offsetof
    offsetof(ngx_http_my_loc_conf_t, enable_cache)
    
  • 为什么需要
    • Nginx 的 set 函数是通用的(如 ngx_conf_set_flag_slot)。
    • 它通过 void *conf + offset 的方式,动态定位到具体字段并写入值。
    • 这是实现“一套解析函数,适配所有模块”的关键设计!

✅ 示例:

typedef struct {
    ngx_flag_t  gzip;
    size_t      buffer_size;
} my_conf_t;

// 指令定义:
{ ngx_string("gzip"), ..., offsetof(my_conf_t, gzip), ... }

set 函数就能把 on 写入 conf->gzip


6. void *post

  • 作用后处理回调指针,通常指向 ngx_conf_post_t 类型。
  • 用途
    • 在值被写入后执行额外操作(如校验范围、触发初始化、设置全局变量)
    • 例如:检查 worker_connections 是否超过系统限制
使用方式:
static ngx_conf_post_t my_post = { ngx_my_post_handler };

static ngx_command_t cmds[] = {
    { ..., &my_post },
};

static char *
ngx_my_post_handler(ngx_conf_t *cf, void *data, void *conf)
{
    ngx_flag_t *fp = conf;
    if (*fp) {
        // do something when enabled
    }
    return NGX_CONF_OK;
}

⚠️ 注意:不是所有指令都需要 post,很多简单指令设为 NULL


🧩 完整示例:定义一个 my_cache on|off; 指令

// 1. 配置结构体
typedef struct {
    ngx_flag_t  my_cache;
} ngx_http_my_loc_conf_t;

// 2. 后处理(可选)
static ngx_conf_post_t my_cache_post = { NULL }; // 这里省略

// 3. 指令定义
static ngx_command_t ngx_http_my_commands[] = {
    { ngx_string("my_cache"),
      NGX_HTTP_LOC_CONF | NGX_CONF_FLAG,
      ngx_conf_set_flag_slot,                 // 使用内置解析函数
      NGX_HTTP_LOC_CONF_OFFSET,               // 作用于 location 配置
      offsetof(ngx_http_my_loc_conf_t, my_cache), // 写入 my_cache 字段
      NULL },                                 // 无 post handler

    ngx_null_command
};

配置文件中即可使用:

location / {
    my_cache on;
}

✅ 总结:ngx_command_t 的设计哲学

特点 说明
声明式 模块只需“声明”指令规则,无需手动解析
通用性 通过 offset + set 机制,一套解析函数服务所有模块
类型安全 type 字段在解析前就做上下文和参数校验
可扩展 支持自定义 setpost 实现任意逻辑

这个结构体是 Nginx 高度模块化、配置驱动架构的基石之一。

如果你正在开发 Nginx 模块,理解 ngx_command_t必经之路

三、struct ngx_module_s结构体

struct ngx_module_s(通常通过 typedef 称为 ngx_module_t)是 Nginx 模块系统的核心结构体。每一个 Nginx 模块(无论是 HTTP 模块、事件模块、核心模块还是第三方模块)都必须定义一个类型为 ngx_module_t 的全局变量,用于向 Nginx 内核“注册”自身的能力、配置、生命周期回调等信息。

下面我们将逐字段详细解析其作用、设计意图和使用方式


🧱 整体结构概览

struct ngx_module_s {
    // 1. 元信息与 ABI 兼容性字段
    ngx_uint_t            ctx_index;
    ngx_uint_t            index;
    char                 *name;
    ngx_uint_t            spare0;
    ngx_uint_t            spare1;
    ngx_uint_t            version;
    const char           *signature;

    // 2. 模块核心功能描述
    void                 *ctx;          // 模块上下文(类型由 module type 决定)
    ngx_command_t        *commands;     // 配置指令列表
    ngx_uint_t            type;         // 模块类型(NGX_HTTP_MODULE 等)

    // 3. 生命周期回调函数(按启动/关闭顺序)
    ngx_int_t (*init_master)(ngx_log_t *log);
    ngx_int_t (*init_module)(ngx_cycle_t *cycle);
    ngx_int_t (*init_process)(ngx_cycle_t *cycle);
    ngx_int_t (*init_thread)(ngx_cycle_t *cycle);
    void      (*exit_thread)(ngx_cycle_t *cycle);
    void      (*exit_process)(ngx_cycle_t *cycle);
    void      (*exit_master)(ngx_cycle_t *cycle);

    // 4. 预留扩展字段(用于未来兼容)
    uintptr_t             spare_hook0 ... spare_hook7;
};

🔍 一、元信息与 ABI 兼容性字段(前7个)

这些字段主要用于 模块识别、加载校验和内部索引管理,通常由宏 NGX_MODULE_V1 自动初始化。

1. ngx_uint_t ctx_index

  • 作用:该模块在其同类模块中的索引
  • 示例:所有 NGX_HTTP_MODULE 类型的模块会被放入一个数组,ctx_index 表示它在该数组中的位置。
  • 用途:用于快速定位模块上下文(如 HTTP 模块的 main_confsrv_conf 数组)。
  • 初始化:设为 NGX_MODULE_UNSET_INDEX(即 (ngx_uint_t)-1),由 Nginx 启动时自动分配。

2. ngx_uint_t index

  • 作用:该模块在所有已加载模块中的全局唯一索引
  • 用途:用于通用模块遍历、日志标记等。
  • 同样由 Nginx 自动分配

3. char *name

  • 作用:模块名称(字符串)。
  • 实际使用:很少用到,通常设为 NULL
  • 调试时可能有用

4–5. spare0, spare1

  • 保留字段,必须初始化为 0
  • 用于未来扩展,保持结构体对齐或添加新字段而不破坏 ABI。

6. ngx_uint_t version

  • 作用Nginx 核心版本号(如 1022001 表示 1.22.1)。
  • 必须等于编译时的 nginx_version
  • 用途:防止加载用不同版本 Nginx 编译的模块(避免 ABI 不兼容导致崩溃)。

7. const char *signature

  • 作用模块签名字符串,包含:
    • 操作系统类型(Linux/FreeBSD)
    • 编译器(gcc/clang)
    • 编译选项(是否启用 -O2--with-debug 等)
    • 内存对齐方式
    • 指针大小等
  • 生成方式:在 auto/configure 阶段自动生成,定义在 objs/ngx_auto_config.h 中。
  • 用途:严格校验模块是否与当前 Nginx 二进制完全兼容。

✅ 这7个字段通常用 NGX_MODULE_V1 宏一键初始化。


🔧 二、模块核心功能描述(中间3个)

这是模块“能力”的核心声明。

8. void *ctx

  • 作用模块上下文指针,其真实类型由 type 字段决定。
  • 关键点:这是一个泛型指针,Nginx 根据模块类型进行强制转换。
常见类型对应关系:
type ctx 实际类型 说明
NGX_HTTP_MODULE ngx_http_module_t* 包含 create/init 回调,用于创建 main/srv/loc 配置
NGX_CORE_MODULE ngx_core_module_t* ngx_errlog_module
NGX_EVENT_MODULE ngx_event_module_t* 事件驱动模型(epoll/kqueue)
NGX_MAIL_MODULE ngx_mail_module_t* 邮件代理模块

✅ 示例(HTTP 模块):

static ngx_http_module_t ngx_http_my_ctx = {
    NULL,                          /* preconfiguration */
    ngx_http_my_init,              /* postconfiguration */
    NULL,                          /* create main conf */
    NULL,                          /* init main conf */
    NULL,                          /* create srv conf */
    NULL,                          /* merge srv conf */
    ngx_http_my_create_loc_conf,   /* create loc conf */
    ngx_http_my_merge_loc_conf     /* merge loc conf */
};

ngx_module_t ngx_http_my_module = {
    NGX_MODULE_V1,
    &ngx_http_my_ctx,   // ← ctx 指向 ngx_http_module_t
    ngx_http_my_commands,
    NGX_HTTP_MODULE,
    // ... callbacks ...
};

9. ngx_command_t *commands

  • 作用:指向该模块支持的配置指令数组(以 ngx_null_command 结尾)。
  • 用途:Nginx 解析配置文件时,根据指令名匹配到此数组中的条目,并调用其 set 函数。
  • 若无配置项,可设为 NULL

10. ngx_uint_t type

  • 作用模块类型,决定 Nginx 如何处理该模块。
  • 常用值
    #define NGX_CORE_MODULE      0x45524F43   // 'CORE'
    #define NGX_CONF_MODULE      0x464E4F43   // 'CONF'
    #define NGX_EVENT_MODULE     0x544E5645   // 'EVNT'
    #define NGX_HTTP_MODULE      0x50545448   // 'HTTP'
    #define NGX_MAIL_MODULE      0x4C49414D   // 'MAIL'
    #define NGX_STREAM_MODULE    0x54414552   // 'REAT' (Stream)
    
  • 重要性:决定了:
    • ctx 的解释方式
    • 模块在启动流程中的处理阶段
    • 配置结构体的创建时机

⏳ 三、生命周期回调函数(7个函数指针)

Nginx 在不同阶段调用这些回调,实现模块的初始化和清理。

回调函数 调用时机 参数 返回值 典型用途
init_master Master 进程启动早期(仅一次) ngx_log_t *log NGX_OK / NGX_ERROR 初始化全局资源(如共享内存、信号)
init_module 所有模块加载完成后,fork 子进程前 ngx_cycle_t *cycle NGX_OK / NGX_ERROR 初始化模块级资源(如连接池、监听 socket)
init_process 每个 Worker 进程启动时 ngx_cycle_t *cycle NGX_OK / NGX_ERROR 初始化进程私有资源(如定时器、event loop)
init_thread 线程池启用时(极少用) ngx_cycle_t *cycle NGX_OK / NGX_ERROR 初始化线程局部数据
exit_thread 线程退出时 ngx_cycle_t *cycle void 清理线程资源
exit_process Worker 进程退出时 ngx_cycle_t *cycle void 清理进程资源(如关闭 fd、释放内存)
exit_master Master 进程退出时 ngx_cycle_t *cycle void 清理全局资源

💡 注意

  • 大多数模块只用 init_moduleinit_process
  • 如果不需要某阶段回调,设为 NULL
  • init_process 是最常用的,因为 Worker 进程在此时才真正开始工作。

🧩 四、预留扩展字段(8个 spare_hook

uintptr_t spare_hook0 ... spare_hook7;
  • 作用:为未来 Nginx 版本预留的回调或字段,保证结构体大小稳定。
  • 当前必须初始化为 0(通常由 NGX_MODULE_V1_PADDING 宏完成)。
  • 设计哲学:避免因新增字段导致旧模块因结构体大小不匹配而崩溃。

✅ 使用 NGX_MODULE_V1_PADDING 宏来填充这些字段。


✅ 完整模块定义示例(HTTP 模块骨架)

static ngx_http_module_t ngx_http_my_module_ctx = {
    NULL, NULL, NULL, NULL, NULL, NULL,
    ngx_http_my_create_loc_conf,
    ngx_http_my_merge_loc_conf
};

static ngx_command_t ngx_http_my_commands[] = {
    { ngx_string("my_flag"),
      NGX_HTTP_LOC_CONF | NGX_CONF_FLAG,
      ngx_conf_set_flag_slot,
      NGX_HTTP_LOC_CONF_OFFSET,
      offsetof(ngx_http_my_loc_conf_t, flag),
      NULL },
    ngx_null_command
};

ngx_module_t ngx_http_my_module = {
    NGX_MODULE_V1,
    &ngx_http_my_module_ctx,        /* ctx */
    ngx_http_my_commands,           /* commands */
    NGX_HTTP_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
};

📌 总结:ngx_module_t 的设计思想

特点 说明
统一接口 所有模块通过同一结构体向内核注册
类型驱动 type 决定 ctx 解释方式和处理流程
生命周期管理 提供完整的 init/exit 钩子
ABI 安全 通过 version + signature 防止不兼容模块加载
可扩展性 预留字段 + 宏封装,支持未来演进

理解 ngx_module_t 是深入 Nginx 模块开发的基石。它体现了 Nginx 高度模块化、低耦合、高性能的架构哲学。

如果你正在编写 Nginx 模块,务必正确初始化这个结构体!

四、Nginx HTTP 模块系统

ngx_http_module_tNginx HTTP 模块系统中的核心结构体之一,用于定义一个 HTTP 模块在整个 Nginx 配置生命周期中各个阶段的行为。它本质上是一个回调函数表(callback table),通过函数指针将模块的配置逻辑“钩入”到 Nginx 的配置解析与初始化流程中。

下面我们将逐字段详细分析这个结构体的每一个成员,包括其作用、调用时机、参数含义、返回值规范以及典型使用场景。


结构体定义回顾

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;

一、配置前/后处理阶段

1. preconfiguration

ngx_int_t (*preconfiguration)(ngx_conf_t *cf);
  • 作用:在 Nginx 开始解析 HTTP 配置块(即 http { ... }之前调用。
  • 调用时机:仅在主配置阶段(main configuration phase)中,进入 http 块解析前。
  • 用途
    • 注册变量(如 ngx_http_add_variable
    • 添加阶段处理器(phase handlers),但注意:通常在 postconfiguration 中注册更安全
    • 初始化一些全局资源(如共享内存、哈希表等)
  • 返回值
    • NGX_OK:成功
    • NGX_ERROR:失败,Nginx 启动终止
  • 注意:此时所有配置结构体尚未创建,不能访问 srv_confloc_conf

✅ 典型用法:注册自定义变量(如 $my_var


2. postconfiguration

ngx_int_t (*postconfiguration)(ngx_conf_t *cf);
  • 作用:在 整个 HTTP 配置解析完成之后 调用(即所有 serverlocation 块都已解析完毕)。
  • 调用时机:HTTP 配置解析结束、worker 进程启动前。
  • 用途
    • 最关键的用途:向 HTTP 请求处理的 11 个阶段(phases)中插入自己的 handler(如 ngx_http_core_rewrite_phasengx_http_core_access_phase 等)
    • 完成模块的最终初始化(如构建查找表、验证配置一致性等)
  • 返回值:同上,NGX_OKNGX_ERROR
  • 重要性:绝大多数模块在此处注册 handler。

✅ 典型用法:

ngx_http_core_main_conf_t *cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers.elts = ...;

二、Main 配置(http 块级别)

Nginx 的配置是分层的:mainserverlocation。每个层级都有独立的配置结构体。

3. create_main_conf

void *(*create_main_conf)(ngx_conf_t *cf);
  • 作用:为当前模块在 http { ... } 块中创建主配置结构体(main configuration context)。
  • 调用时机:当 Nginx 解析到 http 块时,为每个 HTTP 模块调用一次。
  • 返回值
    • 成功:指向新分配的配置结构体(如 my_module_main_conf_t *
    • 失败:返回 NULL(但通常应使用 ngx_pcalloc 并检查)
  • 典型实现
    static void *
    ngx_http_my_module_create_main_conf(ngx_conf_t *cf)
    {
        ngx_http_my_module_main_conf_t *mcf;
        mcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_my_module_main_conf_t));
        if (mcf == NULL) {
            return NULL;
        }
        // 初始化默认值,如 mcf->flag = NGX_CONF_UNSET;
        return mcf;
    }
    

⚠️ 注意:不要在这里做复杂逻辑,只负责分配和设默认值。


4. init_main_conf

char *(*init_main_conf)(ngx_conf_t *cf, void *conf);
  • 作用:在 http 块解析完成后,对主配置进行最终初始化或验证
  • 调用时机:在 http 块解析结束、进入 server 块之前。
  • 参数
    • conf:即 create_main_conf 返回的指针
  • 返回值
    • 成功:返回 NGX_CONF_OK(即 (char *)NULL
    • 失败:返回错误信息字符串(如 "my_module: missing required parameter"
  • 用途
    • 检查必填项是否设置
    • NGX_CONF_UNSET 替换为真实默认值
    • 构建内部数据结构(如正则表达式编译)

✅ 示例:

if (mcf->size == NGX_CONF_UNSET_SIZE) {
    mcf->size = 1024;
}

三、Server 配置(server 块级别)

5. create_srv_conf

void *(*create_srv_conf)(ngx_conf_t *cf);
  • 作用:为每个 server { ... } 块创建该模块的 server 级配置。
  • 调用时机:每当遇到一个新的 server 块时调用。
  • 返回值:新分配的 server 配置结构体指针。
  • 注意:不同 server 块有各自独立的配置实例。

💡 提示:如果模块不关心 server 级配置,可返回 NULL,但通常仍需创建空结构以支持 merge。


6. merge_srv_conf

char *(*merge_srv_conf)(ngx_conf_t *cf, void *prev, void *conf);
  • 作用:将父级(通常是 main)配置合并到当前 server 配置中。
  • 参数
    • prev:上级配置(通常是 main conf)
    • conf:当前 server 的配置
  • 调用时机:在 server 块解析完成后。
  • 返回值
    • 成功:NGX_CONF_OK
    • 失败:错误字符串
  • 合并逻辑
    • 如果 conf 中某字段未设置(如 == NGX_CONF_UNSET),则从 prev 继承
    • 若两者都未设置,则使用硬编码默认值
  • 重要性:实现配置继承机制的关键!

✅ 示例:

if (conf->timeout == NGX_CONF_UNSET_MSEC) {
    conf->timeout = prev->timeout; // 从 main 继承
}
if (conf->timeout == NGX_CONF_UNSET_MSEC) {
    conf->timeout = 60000; // 默认 60s
}

四、Location 配置(location 块级别)

7. create_loc_conf

void *(*create_loc_conf)(ngx_conf_t *cf);
  • 作用:为每个 location /xxx { ... } 块创建 location 级配置。
  • 调用时机:解析每个 location 块时。
  • 特点:一个 server 可包含多个 location,每个都有独立配置。

8. merge_loc_conf

char *(*merge_loc_conf)(ngx_conf_t *cf, void *prev, void *conf);
  • 作用:将上级配置(可能是 server 或另一个 location)合并到当前 location 配置。
  • 参数
    • prev:父级配置(可能是 server conf 或嵌套 location 的外层 conf)
    • conf:当前 location 的配置
  • 调用时机location 块解析完成后。
  • 合并策略:同 merge_srv_conf,但层级更深(main → server → location → nested location)

🔁 合并顺序示例:

http { 
    my_param 1;           // main
    server {
        my_param 2;       // server overrides main
        location /a {
            my_param 3;   // location overrides server
        }
    }
}

/amerge_loc_conf 中,prev 是 server conf(值=2),conf 是 loc conf(值=3),若 loc 未设,则继承 2。


总结:配置层级与调用顺序

阶段 函数 调用次数 说明
预处理 preconfiguration 1 次 HTTP 配置开始前
创建 main create_main_conf 1 次 创建 http 级配置
初始化 main init_main_conf 1 次 验证/完善 main 配置
创建 server create_srv_conf 每个 server 一次
合并 server merge_srv_conf 每个 server 一次 main → server
创建 location create_loc_conf 每个 location 一次
合并 location merge_loc_conf 每个 location 一次 server → location
后处理 postconfiguration 1 次 所有配置解析完毕后

实际开发建议

  1. 所有 create_*_conf 函数:只做内存分配和默认值设置(用 NGX_CONF_UNSET 表示未设置)。
  2. 所有 merge_*_conf 函数:实现继承逻辑,最后赋予真正默认值。
  3. postconfiguration 是注册 handler 的黄金位置
  4. 如果模块不需要某层配置(如无 server 级参数),可设对应函数为 NULL,但 Nginx 仍可能调用,所以通常提供空实现更安全。
  5. 使用 NGX_CONF_UNSET, NGX_CONF_UNSET_PTR, NGX_CONF_UNSET_SIZE 等宏来标记“未设置”。

示例:一个最小可行的 ngx_http_module_t

static ngx_http_module_t ngx_http_my_module_ctx = {
    NULL,                                  /* preconfiguration */
    ngx_http_my_module_init,               /* postconfiguration */

    ngx_http_my_module_create_main_conf,   /* create_main_conf */
    ngx_http_my_module_init_main_conf,     /* init_main_conf */

    NULL,                                  /* create_srv_conf */
    NULL,                                  /* merge_srv_conf */

    ngx_http_my_module_create_loc_conf,    /* create_loc_conf */
    ngx_http_my_module_merge_loc_conf      /* merge_loc_conf */
};

通过这个结构体,Nginx 实现了高度模块化、配置继承、阶段化初始化的架构,使得第三方模块可以无缝集成到核心流程中,而无需修改 Nginx 主干代码。这是 Nginx 模块系统设计的精髓所在。

五、配置级别

在 Nginx 配置中,配置级别(Contexts) 是指指令可以被放置的逻辑层级或作用域。不同指令只能出现在特定的上下文中。以下是 Nginx 官方文档定义的所有标准配置级别(上下文),按层次结构从外到内排列:


✅ 1. main(主/全局上下文)

  • 位置:配置文件最顶层,不在任何块内。
  • 作用范围:整个 Nginx 实例。
  • 典型指令
    • user
    • worker_processes
    • error_log
    • pid
    • worker_rlimit_nofile
    • daemon
    • master_process

⚠️ 此上下文不能包含其他块(如 serverlocation),但可以包含 eventshttp


✅ 2. events

  • 位置:只能在 main 上下文中。
  • 作用:配置连接处理(事件驱动模型)。
  • 典型指令
    • worker_connections
    • use(如 epoll, kqueue
    • multi_accept
    • accept_mutex

📌 一个配置文件中只能有一个 events 块。


✅ 3. http

  • 位置:只能在 main 上下文中。
  • 作用:定义 HTTP 服务器相关配置。
  • 可包含upstreammapgeoserver 等块。
  • 典型指令
    • include
    • sendfile
    • tcp_nopush
    • keepalive_timeout
    • gzip
    • log_format
    • access_log
    • client_max_body_size

📌 一个配置文件中通常只有一个 http 块(虽然语法允许多个,但不推荐)。


✅ 4. mail(仅限 Nginx 邮件代理模块)

  • 位置:在 main 上下文中(与 http 同级)。
  • 作用:配置 IMAP/POP3/SMTP 代理。
  • 可包含server 块(邮件协议用)。
  • 注意:需编译时启用 --with-mail 模块。

❗ 如果你只用 Nginx 做 Web 服务器,通常不会用到 mail 上下文。


✅ 5. stream(TCP/UDP 反向代理)

  • 位置:在 main 上下文中(与 http 同级)。
  • 作用:用于四层(L4)负载均衡,代理 TCP/UDP 流量(如 MySQL、Redis、DNS)。
  • 可包含serverupstream 块。
  • 典型指令
    • proxy_pass
    • proxy_timeout
    • listen(指定端口和协议)

🔧 需要 --with-stream 模块(现代发行版默认包含)。


✅ 6. server

  • 出现位置
    • http 块中 → 用于 HTTP 虚拟主机
    • mail 块中 → 用于邮件服务
    • stream 块中 → 用于 TCP/UDP 服务
  • 作用:定义一个虚拟主机或监听服务。
  • 典型指令(HTTP 中)
    • listen
    • server_name
    • root
    • index
    • ssl_certificate
    • return, rewrite

📌 这是 Nginx 虚拟主机的核心单元。


✅ 7. location

  • 位置:只能在 httpserver 块中(即 HTTP 的 server 内)。
  • 作用:匹配 URI 路径,定义请求处理逻辑。
  • 匹配方式:前缀匹配、正则匹配、精确匹配等。
  • 典型指令
    • proxy_pass
    • fastcgi_pass
    • alias
    • try_files
    • deny/allow

location 不能出现在 streammailserver 中。


✅ 8. upstream

  • 位置:在 httpstream 块中(不能在 server 内)。
  • 作用:定义后端服务器组,用于负载均衡。
  • 典型指令
    • server(upstream 内部的 server 指令,不是 server 块!)
    • least_conn
    • ip_hash
    • keepalive
upstream backend {
    server 10.0.0.1:8080;
    server 10.0.0.2:8080;
}

✅ 9. map

  • 位置:在 http 块中。
  • 作用:创建变量映射(基于其他变量的值)。
  • 示例
    map $http_user_agent $is_mobile {
        default 0;
        "~*mobile" 1;
    }
    

✅ 10. geo

  • 位置:在 http 块中。
  • 作用:根据客户端 IP 地址创建变量(常用于地域控制)。
  • 示例
    geo $country {
        default ZZ;
        10.0.0.0/8 US;
        192.168.0.0/16 CN;
    }
    

✅ 11. limit_req_zone / limit_conn_zone

  • 位置:在 http 块中。
  • 作用:定义限流/限连区域(变量 + 共享内存区)。
  • 配合指令limit_reqlimit_conn(用在 serverlocation 中)。

✅ 12. if

  • 位置:可在 serverlocation 中(不推荐在 http 中使用)。
  • 注意if 在 Nginx 中有陷阱(如重写上下文问题),应谨慎使用。
  • 常见用途:条件判断(但优先考虑 maptry_files)。

✅ 13. 其他特殊上下文(较少见)

上下文 说明
split_clients 用于 A/B 测试,基于变量分流
types 定义 MIME 类型(通常在 http 中)
charset_map 字符集转换映射
perl / perl_set Perl 模块集成(需编译支持)

📌 总结:Nginx 主要配置级别层级图

main
├── events
├── http
│   ├── upstream
│   ├── map
│   ├── geo
│   ├── server
│   │   └── location
│   │       └── if (谨慎)
│   └── ...
├── stream
│   ├── upstream
│   └── server
└── mail
    └── server

💡 每个指令的可用上下文可在 Nginx 官方文档 中查到,例如 proxy_pass 只能在 locationif in locationlimit_except 中使用。

总结

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐