源码安装 nginx 后模块加载失败,本质是编译未包含、运行时不可加载或配置引用错误;需依次验证 nginx -v 中 configure arguments 是否含对应模块、动态模块文件是否合规(elf 共享对象、符号导出、ldd 依赖正常)、load_module 是否置于 main 上下文且路径正确,并用 nginx -e stderr 强制终端输出加载错误。

源码安装 Nginx 后服务启动时无法加载模块,常见于 nginx -t 报 unknown directive、module not found 或直接段错误(Segmentation fault),本质是模块未被识别或初始化失败。排查需紧扣“编译时是否包含”、“运行时是否可加载”、“配置中是否正确引用”三层逻辑。
确认模块是否已编译进 Nginx 二进制
很多“加载失败”其实根本没编译进去——Nginx 不会报错,只是忽略未启用的指令:
- 执行
/usr/local/nginx/sbin/nginx -V(大写 V),查看 configure arguments 行: 若配置用了stream { }却没看到--with-stream; 若用了ssl_certificate却没有--with-http_ssl_module; 若用了 Lua 指令却没含--add-module=或--add-dynamic-module=路径 → 说明该模块压根不在二进制里 - 对比你当初
./configure命令和nginx -V输出是否一致,尤其注意路径拼写、空格、转义符号等细节
验证动态模块文件本身是否合规
若使用 load_module 加载 .so 文件,模块文件必须结构完整、依赖就位:
- 检查
.so文件是否存在、可读:ls -l /usr/lib/nginx/modules/ngx_http_echo_module.so - 确认它是合法共享对象:
file /path/to/module.so应输出ELF 64-bit LSB shared object - 检查导出符号:
objdump -t module.so | grep nginx_module必须有对应模块名的全局符号(如ngx_http_echo_module) - 运行
ldd module.so,重点看libnginx.so(Nginx 1.15+ 提供的兼容库)是否找到;若提示not found,说明模块编译时缺失--with-compat或运行时路径未纳入LD_LIBRARY_PATH
检查配置中模块加载与使用是否匹配
即使模块存在且编译正确,配置写错也会导致静默失效或启动崩溃:
-
load_module指令必须放在main上下文(即events块之前),不能在http或server内 - 路径必须是绝对路径,且与
nginx -V中--modules-path值一致;若不一致,需用完整路径写明,如load_module /opt/modules/xxx.so; - 确保配置中使用的指令(如
echo "hello";)确实属于该模块,并且未被其他同名指令覆盖(例如多个 echo 模块冲突) - 临时注释掉所有
load_module,执行nginx -t;若通过,再逐个放开并测试,快速定位问题模块
强制输出加载过程日志定位卡点
模块加载失败常发生在初始化早期,error.log 可能为空。此时必须让错误直出终端:
- 运行:
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf -e stderr -t这会绕过日志系统,把模块加载失败、符号缺失、ABI 不匹配等错误直接打印到屏幕 - 典型输出如:
unknown directive "lua_code_cache"(Lua 模块未编译)、failed to load module "/xxx.so": undefined symbol: ngx_http_upstream_check_init(ABI 不匹配) - 配合
strace -e trace=openat,open,close nginx -t -e stderr 2>&1 | grep -i "module\|so",可观察 Nginx 实际尝试打开哪些模块路径











