nginx与java应用协同实现端到端可观测:java侧暴露actuator端点、集成opentelemetry/skywalking主动埋点并透传trace头;nginx侧用$request_id透传打标、结构化日志记录trace字段,并通过skywalking-nginx-lua上报入口span。

要让 Nginx 和 Java 应用共同支撑全面监控与链路追踪,关键不是让 Nginx 去“采集”Java 指标,而是各司其职:Java 应用主动暴露可观测性端点并生成 trace 上下文,Nginx 作为入口网关负责透传、打标、记录和轻量埋点,两者协同才能形成端到端的可观测闭环。
Java 应用侧:暴露指标 + 主动埋点
Spring Boot 项目需启用 Actuator 并集成 OpenTelemetry 或 SkyWalking Agent:
- 添加依赖:
spring-boot-starter-actuator、micrometer-registry-prometheus(用于 JVM 指标),以及opentelemetry-javaagent.jar或skywalking-agent(用于链路追踪) - 配置
application.yml开放监控端点:management.endpoints.web.exposure.include: health,info,metrics,prometheus,threaddump - 启动时注入探针:
java -javaagent:/path/to/opentelemetry-javaagent.jar \-Dotel.service.name=order-service \-Dotel.exporter.otlp.endpoint=http://otel-collector:4317 \-jar app.jar - 确保所有 HTTP 接口都透传
traceparent或X-B3-TraceId,并在日志中通过 MDC 注入 trace_id,例如 Logback 中配置:%X{trace_id:-} %X{span_id:-} [%thread] %-5level %logger{36} - %msg%n
Nginx 侧:透传 trace ID + 补全上下文
Nginx 不生成完整 span,但必须稳定提供请求唯一标识,并保障其全程不丢失:
- 使用内置
$request_id(Nginx ≥ 1.11.0),无需 Lua,天然唯一且高效 - 在
location块内紧邻proxy_pass设置透传头:proxy_set_header X-Request-ID $request_id;proxy_set_header traceparent $http_traceparent; - 若上游未带追踪头,可用
map或 Lua 补充(推荐 map,更轻量):map $http_traceparent $trace_id {"" "${request_id}";default $http_traceparent;} - 避免在
http或server块顶层写proxy_set_header,否则不生效
日志标准化:打通日志串联基础
结构化日志是链路串联的底座,Nginx 日志必须包含可对齐的 trace 字段:
- 自定义
log_format显式记录:log_format trace_log 'req_id:"$request_id" trace_id:"$http_traceparent" status:$status upstream_time:$upstream_response_time rt:$request_time'; - 禁用缓存影响:
location = /actuator/prometheus {add_header Cache-Control "no-cache";proxy_cache_bypass $http_upgrade;} - 所有后端服务日志中的 trace_id 字段名、格式(如 32 位小写 hex)、长度必须完全一致,便于 ELK/Loki 按字段聚合
链路整合:对接后端追踪系统
真正实现“全链路”,靠的是统一协议与协同上报:
- Java 服务用 OpenTelemetry SDK 或 SkyWalking Agent 上报 span 到 OTEL Collector 或 SkyWalking OAP
- Nginx 使用
skywalking-nginx-lua(官方 Lua 探针)上报入口 span,自动与后端链路拼接:
需配置init_worker_by_lua_block设置 service 名,access_by_lua_block启动 tracing,log_by_lua_block完成上报 - 不建议用 nginx-exporter 抓取 Java 指标——它只适配 Nginx 自身状态;JVM 指标由 Prometheus 直连
/actuator/prometheus抓取 - 前端可通过 Nginx 注入
X-Request-ID,再由 JS SDK(如 Sentry)读取并带上报,实现前后端 trace 对齐
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











