Nginx Master进程不执行模块逻辑,仅在启动或reload时解析load_module指令、校验.so路径与ABI兼容性并调用dlopen预加载;真正初始化和功能执行由Worker进程完成。

Nginx 的 Master 进程本身不负责加载或执行动态模块的逻辑功能,它只承担配置解析和模块声明的“登记”工作。真正意义上的模块加载,发生在 Master 启动初期、Worker 进程 fork 之前,且仅限于已编译进二进制或通过 load_module 显式声明的动态模块。
关键点在于:Master 不动态链接代码,也不运行模块代码;它只是读取配置、验证模块路径、把模块信息记入内存结构,然后交由后续流程处理。
load_module 指令由 Master 解析并预检
load_module 必须写在 main context(即 nginx.conf 最顶部、events 块之前)。Master 进程在 ngx_init_cycle() 阶段会:
- 扫描所有
load_module指令 - 将每个
.so文件路径转为绝对路径(若为相对路径,则基于 nginx.conf 所在目录解析) - 调用
dlopen()尝试打开模块文件,并检查其 ABI 兼容性(如 Nginx 版本、OpenSSL/PCRE/zlib 符号是否匹配) - 若失败,
nginx -t会报错(如 “module not found” 或 “undefined symbol”),Master 直接退出
这个过程不涉及模块初始化逻辑——那是在 Worker 进程中完成的。
Master 不调用模块的 init 或 handler 函数
所有模块的 init_module、init_process、HTTP handler/filter 等钩子函数,均由 Worker 进程在各自上下文中调用。Master 从不执行请求处理,也不参与模块功能逻辑。它的角色是协调者,不是执行者。
动态模块的“生效”依赖 reload,而非 Master 主动加载
当你执行 nginx -s reload:
- Master 收到
SIGHUP信号 - 它重新解析整个配置(包括所有
load_module行) - 若路径/权限/ABI 无变化,就复用已
dlopen的句柄;若有变更,则重新dlopen+ 校验 - 随后 fork 新 Worker,旧 Worker 优雅退出
- 新 Worker 在启动时调用各模块的
init_process钩子,正式启用功能
所以,所谓“加载”,其实是 Master 在 reload 时做的一次安全校验与句柄管理,真正的模块能力激活在 Worker 中。
常见误区与实操要点
- ✅
load_module只能出现在全局作用域,写在 http/server/location 内会直接报错 - ✅ 推荐使用绝对路径(如
/usr/lib/nginx/modules/ngx_http_geoip2_module.so),避免路径解析歧义 - ✅ 模块文件需
chmod 644,确保 nginx worker 用户(如 www-data)有读权限 - ❌ 不要指望 Master 在运行时“发现新 .so 并自动加载”——它不会轮询目录,也不会响应文件系统事件
- ❌
nginx -V不显示已加载的动态模块列表,验证方式是看相关指令(如geoip2_country)是否被识别,或观察nginx -t是否通过
不复杂但容易忽略。


















