全链路ID透传需确保CDN、WAF、Nginx每层均启用追加式透传且不覆盖:CDN需放行X-Trace-ID头,WAF禁用头清洗策略,Nginx用$http_x_trace_id而非硬赋值;ID仅在最外层可信入口(如CDN边缘或WAF)生成一次,后端须显式读取并注入MDC,日志格式需支持traceId占位符,逐层验证+内网兜底是关键。

在 CDN → WAF → Nginx 多层级代理链路中透传全链路 ID(如 X-Trace-ID 或 X-Request-ID),核心难点不是“能不能加头”,而是**每一环是否可信、是否默认透传、是否被覆盖或丢弃**。真实生产环境里,ID 断在 WAF 或 CDN 是最常见问题。
确保每层代理都原样透传,不覆盖、不重写
所有中间节点必须明确配置为“追加式透传”,而非“覆盖式赋值”:
- CDN 层(如阿里云 CDN、Cloudflare):需在控制台开启「透传自定义请求头」功能,并显式放行
X-Trace-ID;默认多数 CDN 会过滤未知头,X-开头的头也可能被静默剥离 - WAF 层(如阿里云 Web 应用防火墙、Imperva):检查「HTTP 头处理策略」,确认未启用「清除可疑头」或「标准化请求头」类规则;部分 WAF 默认重写
X-Forwarded-For,也会顺带清空其他X-头 - Nginx 入口层(最终反向代理):禁止使用
proxy_set_header X-Trace-ID $remote_addr这类硬赋值;统一用proxy_set_header X-Trace-ID $http_x_trace_id,保证上游传什么,就往下传什么
入口生成 + 链路守恒:只生成一次,全程不替换
全链路 ID 必须在**最外层可信入口(如 CDN 回源请求或 WAF 转发请求)首次生成**,后续所有环节只透传、不生成、不覆盖:
- 若 CDN 支持边缘脚本(如 Cloudflare Workers、阿里云 CDN 边缘 Node.js),优先在此生成并注入
X-Trace-ID,避免被下游层层覆盖 - 若由 WAF 生成(如部分企业版 WAF 提供 trace-id 插件),则需关闭 Nginx 和后端应用的自动生成逻辑,否则出现多 ID 冲突
- 严禁后端服务收到请求后二次生成 —— 常见错误是 Spring Boot Filter 里检测不到
X-Trace-ID就 fallback 生成,导致链路分裂
后端正确读取与日志落盘
Nginx 透传只是第一步,后端必须可靠提取并注入日志上下文:
- Spring Boot:用
@RequestHeader(value = "X-Trace-ID", required = false)显式接收,再通过MDC.put("traceId", id)注入;禁用任何基于request.getRemoteAddr()的 fallback 逻辑 - 日志格式必须含
%X{traceId}占位符(Logback)或对应字段(如 Log4j2 的%X{traceId}),否则即使 MDC 设置成功,日志里也看不到 - 若使用网关(如 Spring Cloud Gateway),需额外确认其默认不清洗
X-Trace-ID—— 某些版本会自动 strip 掉非标准头
验证与兜底:快速定位断点
上线前务必逐层验证,避免靠猜:
- 在 Nginx access_log 中临时添加
$http_x_trace_id字段,确认 CDN/WAF 是否真正传到了这一层 - 在后端接口加一行 debug 日志:
log.info("Received X-Trace-ID: {}", request.getHeader("X-Trace-ID")),比对各层日志中的值是否一致 - 设置简单兜底:若所有上游都未传,且当前请求来自可信内网 IP(如 CDN 回源段、WAF 出口段),才允许生成新 ID;公网直连请求一律拒绝或打标告警


















