使用 strace 排查 Nginx 静默退出(无错误日志)

      发布在:前端技术      评论:0 条评论

使用 strace 排查 Nginx 静默退出(无错误日志)

背景

  • 系统:OpenCloudOS(基于 CentOS)
  • 环境:宝塔面板安装的 Nginx 1.26,同时启用了免费 WAF(堡塔 free_waf)
  • 现象:
    • nginx -t 测试通过,返回 syntax is oktest is successful
    • 直接运行 /www/server/nginx/sbin/nginx 无任何输出,进程立即退出
    • ps aux | grep nginx 看不到 Nginx 进程
    • 错误日志 /www/server/nginx/logs/error.log 中仅有 signal process started,没有任何 [emerg][error] 记录
    • systemctl start nginx 或面板启动均提示失败

错误日志空白的原因

Nginx 启动过程大致为:解析配置 → 初始化模块(含动态库、Lua 等)→ 打开日志文件 → 绑定端口 → 守护进程化。  
如果在打开日志文件之前就发生致命错误(例如动态库加载失败),Nginx 会直接退出,无法写入任何错误信息。

使用 strace 获取启动过程

strace -f -o /tmp/nginx.trace /www/server/nginx/sbin/nginx -c /www/server/nginx/conf/nginx.conf

  • -f:跟踪子进程(Nginx 会 fork 出 worker)
  • -o:将输出保存到指定文件
  • 后续的命令为 Nginx 启动命令,指定配置文件

命令执行后,Nginx 进程虽然瞬间退出,但整个生命周期的系统调用已记录在 /tmp/nginx.trace 中。查看最后部分:

tail -n 30 /tmp/nginx.trace

关键输出与根因定位

输出末尾出现多次 ENOENT (No such file or directory),然后直接 exit_group(1)

openat(AT_FDCWD, "/www/server/free_waf/cjson.lua", O_RDONLY) = -1 ENOENT
openat(AT_FDCWD, "/www/server/free_waf/cjson.so", O_RDONLY) = -1 ENOENT
openat(AT_FDCWD, "/usr/local/lib/lua/5.1/cjson.so", O_RDONLY) = -1 ENOENT
...
exit_group(1)                     = ?

Nginx 在加载免费 WAF 的 Lua 模块时,试图寻找 cjson 库(cjson.luacjson.so),在所有搜索路径中均未找到,导致模块初始化失败,进程以退出码 1 直接退出。由于此时错误日志尚未打开,故没有任何记录。

根因:免费 WAF 组件安装不完整,缺少 Lua CJSON 库。

解决方案

方法一:重装免费 WAF(推荐)

宝塔面板 → 软件商店 → 卸载“堡塔免费 WAF”,再重新安装,会自动补全 /www/server/free_waf/ 下的依赖,包括 cjson.so

方法二:临时禁用 WAF

编辑 /www/server/nginx/conf/nginx.conf,注释掉引用 free_wafinclude 行,然后启动 Nginx。

方法三:手动安装 lua-cjson

yum install -y lua-cjson
find /usr -name "cjson.so"          # 确认库文件位置,例如 /usr/lib64/lua/5.1/cjson.so
ln -sf /usr/lib64/lua/5.1/cjson.so /www/server/free_waf/cjson.so

修复后重新启动 Nginx,ps aux | grep nginx 应能看到 master 和 worker 进程。

总结

当服务因过早崩溃而无法写入日志时,strace 可以通过系统调用跟踪记录进程的退出原因。以下场景特别适用:

  • 启动后瞬间退出且无日志
  • 动态库(.so)缺失
  • 权限拒绝(EACCES
  • 引用的外部文件不存在

常用排查命令:

strace -f -o /tmp/trace.log <启动命令>
tail -n 50 /tmp/trace.log


热门推荐