Nginx 通过 $request_id 变量(≥1.11.0)生成唯一请求ID,配合 add_header、log_format 和 map 指令实现透传、记录与兜底,并需后端服务协同注入MDC及下游转发,构成全链路追踪。

在 Nginx 中实现全局请求 ID 追踪,核心是为每个进入的请求生成唯一标识(如 X-Request-ID),并在整个请求生命周期中透传、记录和转发。Nginx 本身不内置分布式追踪能力,但可通过模块和配置组合达成轻量级、高可用的请求 ID 全局追踪。
启用并生成请求 ID
Nginx 官方模块 ngx_http_core_module 自 1.11.0 起支持 $request_id 变量,它基于随机数和时间戳自动生成 16 字节(32 位十六进制)的唯一字符串,每个请求独立且稳定(同一请求内多次引用值不变)。
你无需额外安装模块,只需确保 Nginx 版本 ≥ 1.11.0(推荐 ≥ 1.19.0)。确认方式:
nginx -v
注入请求 ID 到响应头与日志
让客户端和服务端都能看到该 ID,需将其写入响应头,并记录到访问日志中,便于问题定位与链路对齐。
- 在
server或location块中添加:add_header X-Request-ID $request_id always; - 自定义日志格式(推荐在
http块中定义):log_format main '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_request_id" "$request_id";'
注意:这里同时记录了客户端传入的X-Request-ID(用于透传场景)和 Nginx 生成的$request_id(用于兜底)。 - 在
access_log指令中使用该格式:access_log /var/log/nginx/access.log main;
透传上游请求 ID(兼容外部调用)
若前端网关或客户端已携带 X-Request-ID,应优先沿用而非覆盖,保证全链路 ID 一致。可借助 map 指令实现“有则用之,无则生成”逻辑:
在 http 块顶部添加:
map $http_x_request_id $req_id {<br>
default $http_x_request_id;<br>
"" $request_id;<br>
}然后替换所有 $request_id 为 $req_id:
add_header X-Request-ID $req_id always;- 日志格式中也改用
$req_id(如"$req_id") - 向后端转发时透传:
proxy_set_header X-Request-ID $req_id;
与后端服务协同(关键补充)
Nginx 的请求 ID 只是链路起点。要实现真正“全局”追踪,还需后端服务配合:
- 后端收到
X-Request-ID后,应将其作为 MDC(Mapped Diagnostic Context)或日志上下文字段,确保所有日志行都带上该 ID; - 下游调用(如 RPC、HTTP)时,主动将该 ID 写入请求头(如
X-Request-ID或trace-id); - 若使用 OpenTelemetry / Jaeger / Zipkin,可将
$req_id作为 trace ID 的基础值(需注意格式兼容性,如长度、字符集)。
这样,从前端发起、经 Nginx、再到各微服务的日志和指标,就能通过同一个 ID 关联分析。


















