nginx ≥1.11.0(推荐≥1.19.0)原生支持$request_id,需在location块中配置proxy_set_header x-request-id $request_id透传,并在log_format中显式记录"$request_id",再由后端统一读取、复用并延续该id实现全链路追踪闭环。

要让 Nginx 支持高效的请求 ID 追踪与性能分析,核心是用好内置 $request_id 变量,并围绕它构建“生成—透传—记录—协同”四层闭环。不需要额外模块、不依赖 Lua,只要版本 ≥ 1.11.0(推荐 ≥ 1.19.0),配置得当就能稳定运行。
确认并启用 $request_id
Nginx 自 1.11.0 起原生支持 $request_id,每次请求自动生成 32 位十六进制唯一字符串(如 e9a8b7c6d5f4a3b2c1e0f9d8a7b6c5d4),无需初始化或加载模块。
- 执行
nginx -v确认版本;若低于 1.11.0,必须升级 - 无需
set或lua初始化,变量在请求进入时自动可用 - 验证方式:在
log_format中加入$request_id,重启后查 access 日志是否稳定输出非空值
统一透传 X-Request-ID 到后端
这是链路串联的关键动作,必须显式配置,且仅在 location 块内生效。
-
proxy_set_header X-Request-ID $request_id;必须写在proxy_pass之前 - 不要加引号:
proxy_set_header X-Request-ID $request_id;✅,"$request_id"❌(旧版可能不展开) - 多个 upstream 或路径需分别配置,
http或server块顶层写无效 - 可同时设
X-Trace-ID $request_id作为 trace ID 的 fallback,但避免混用 W3C 规范头(如traceparent)造成解析冲突
可靠记录 request_id 到日志
日志是问题定位的第一现场,必须确保字段稳定、可解析、易对齐。
- 定义
log_format时直接用$request_id,别依赖$http_x_request_id(客户端不带就为空) - 推荐格式片段:
log_format main '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" req_id:"$request_id"'; - 引号包裹
"$request_id"更利于 Logstash/Grok 解析,防止十六进制被截断 - 启用该格式:
access_log /var/log/nginx/access.log main;
与后端服务协同形成闭环
Nginx 只管“开头一公里”,后端需接住并延续这个 ID,才能真正实现跨系统追踪。
- Spring Boot 项目:用 Filter 提取
X-Request-ID,注入 MDC,再配置日志 pattern 如%X{X-Request-ID:-} - Go Gin 框架:中间件读取
c.Request.Header.Get("X-Request-ID"),注入 zap 或 logrus 的上下文字段 - 下游调用时:所有 HTTP/RPC 请求头中必须复用该
X-Request-ID,禁止覆盖或丢弃 - APM 工具(如 Datadog、SkyWalking):可将
X-Request-ID映射为 trace ID 字段,作为轻量级 trace 上报基础
不复杂但容易忽略——关键是每个环节都用同一个 ID、同一命名、同一落盘方式。从 Nginx 到后端日志再到 APM 界面,搜索一个 ID 就能串起全链路。











