strace可直接捕获nginx worker进程的系统调用(如openat、connect、epoll_wait等)及错误码,精准定位403/404、连接拒绝、上游超时等日志无法揭示的问题;需附加到worker进程,结合-e trace、-t、-y等选项聚焦分析,并联动权限、端口、selinux等验证根因。

在 Nginx 故障排查中,strace 是一个直接观察进程与内核交互行为的利器。它不依赖日志或配置语法检查,而是实时捕获系统调用(如 open、read、write、accept、epoll_wait、connect 等)及其返回值、错误码和耗时,特别适合诊断“Nginx 无响应”“连接被拒绝”“静态文件 403/404”“上游超时但 upstream 日志空白”等表层日志无法解释的问题。
确认目标 worker 进程并最小化干扰
Nginx 默认以 master-worker 模式运行,strace 应作用于具体 worker 进程(而非 master),否则会因信号处理复杂性导致误判或阻塞管理功能。建议先停用多 worker,只保留一个便于追踪:
- 临时修改 nginx.conf:
worker_processes 1;,然后nginx -s reload - 用
ps aux | grep 'nginx: worker'找到 PID(例如12345) - 避免 strace 长时间挂载在生产环境主 worker 上;可考虑用
-p动态附加,复现问题后立即 detach
常用 strace 命令组合与关键选项
单纯运行 strace -p 12345 输出过于冗长。推荐以下聚焦式用法:
-
strace -p 12345 -e trace=epoll_wait,accept,connect,openat,read,write -s 128 -T 2>&1 | grep -E "(EACCES|ENOENT|ECONNREFUSED|ETIMEDOUT|EPERM)"
→ 只跟踪关键 I/O 和网络调用,显示调用耗时(-T),截断字符串长度(-s 128),并高亮常见错误 -
strace -p 12345 -f -e trace=%network -o /tmp/nginx-net.strace
→ 跟踪所有网络相关系统调用(包括 fork 出的子进程,如 proxy_pass 触发的 upstream 连接),输出到文件便于后续分析 - 若怀疑文件权限问题:
strace -p 12345 -e trace=openat,stat,fstat -y 2>&1
→-y显示打开的文件路径(需 Linux 3.19+),配合stat可快速定位 403(权限不足)或 404(路径不存在但配置有别名)
从 strace 输出识别典型故障线索
真正有效的排查,是把系统调用错误码映射到实际配置或环境问题:
-
openat(AT_FDCWD, "/usr/share/nginx/html/index.html", O_RDONLY|O_NONBLOCK) = -1 EACCES (Permission denied)
→ 不是文件不存在,而是 nginx worker 用户(如 www-data)对目录或文件缺少执行(x)权限 —— 注意:Linux 中进入目录需父目录有 x 权限 -
connect(3, {sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 ECONNREFUSED (Connection refused)
→ upstream 服务未监听、端口错误、或防火墙拦截;注意检查是否 bind 到 127.0.0.1:8080 而非 0.0.0.0:8080 -
epoll_wait(12, [], 512, 499) = 0(长时间反复出现且无事件)
→ 事件循环空转,可能因配置了错误的 keepalive_timeout、或 upstream 完全无响应导致连接堆积在 epoll 中 -
read(15, "", 16384) = 0(紧接着 close(15))
→ 对端主动关闭连接(如客户端中断),属正常;但若大量出现且伴随 502,需结合 upstream 日志看是否上游提前 reset
配合其他工具交叉验证
strace 提供的是“发生了什么”,但不解释“为什么发生”。需联动验证:
- 查用户权限:
sudo -u www-data ls -ld /path/to/root /path/to/file - 查端口监听:
ss -tlnp | grep :8080或lsof -i :8080 - 查 SELinux(如启用):
ausearch -m avc -ts recent | grep nginx - 对比 strace 时间戳与 access.log 请求时间,确认是否同一请求上下文











