Skip to content

DDK Tracer Starter ​

基于 Micrometer Tracing + OpenTelemetry 的链路追踪,DDK 额外做一件事:每个 HTTP 响应都带上本次请求的 traceId,调用方报障时贴上这个值,就能直接定位整条调用链。

能做什么 ​

text
HTTP 请求
  ServerHttpObservationFilter   HIGHEST_PRECEDENCE + 1   Spring Boot 开启请求 span
  TraceIdResponseFilter         HIGHEST_PRECEDENCE + 2   写入 X-Trace-Id: <traceId>
  DispatcherServlet
    Controller → Service → Repository                    子 span 共享同一个 traceId
能力提供方
Tracer、上下文传播、采样spring-boot-starter-opentelemetry,management.tracing.*
导出到 OTLPopentelemetry-exporter-otlp,management.opentelemetry.tracing.export.otlp.*
日志里的 traceId / spanIdSpring Boot 自动加入日志关联字段,logging.pattern.correlation
traceId 响应头本 starter,ddk.tracer.response-header.*
链路跟随线程池里的任务本 starter,ddk.tracer.async-propagation.*(0.6.0 起)

引入方式 ​

xml
<dependency>
    <groupId>com.domaindrivenkit</groupId>
    <artifactId>ddk-tracer-starter</artifactId>
    <version>${ddk.version}</version>
</dependency>

传递引入 Spring Boot 4 的 spring-boot-starter-opentelemetry(包含 Micrometer Tracing 的 OTel 桥接与 OTLP 导出器),不再引入整个 actuator。

yaml
management:
  tracing:
    sampling:
      probability: 1.0
  opentelemetry:
    tracing:
      export:
        otlp:
          endpoint: http://otel-collector:4318/v1/traces

Spring Boot 4.1 把 OTLP 链路导出的配置移到了 management.opentelemetry.tracing.export.otlp.*,原来的 management.otlp.tracing.* 已标记为过时。

配置项 ​

配置项类型默认值说明
ddk.tracer.response-header.enabledbooleantrue是否把 traceId 写进响应头
ddk.tracer.response-header.nameStringX-Trace-Id响应头名称
ddk.tracer.async-propagation.enabledbooleantrue链路上下文是否跟随任务进入 Spring 的任务线程池(0.6.0 起)

浏览器端要读取这个头,需要在 DDK Web Starter 中配置 ddk.web.cors.exposed-headers=X-Trace-Id。

链路跨线程、跨消息 ​

换了线程的工作默认会各开一条新链路。本 starter 注册一个 ContextPropagatingTaskDecorator,Spring Boot 会把它用到自己创建的任务线程池上,@Async 方法因此留在调用方的链路上。同一个装饰器也带上调用方的 OperatorContext(0.9 起,ddk-core 为它注册了上下文访问器),多租户应用里的 @Async 方法拿得到租户。

集成事件也靠它留在链路上。DDK Event Starter 在事务提交之后用线程池投递事件,把链路上下文写进消息头,消费端再取出来接上:

text
POST /orders                         链路 4bf9...
  └─ order-events publish            同一条链路,在线程池里
       └─ order-events process       同一条链路,在消费方
            └─ stock-events publish  继续往下

应用自己声明了 TaskDecorator 时以应用为准,DDK 不再注册。

装配条件与降级行为 ​

  • 自动配置类:com.ddk.tracer.starter.config.DdkTracerAutoConfiguration,after = MicrometerTracingAutoConfiguration,确保判断 Tracer 是否存在时 Boot 已注册完。
  • 过滤器只在 Servlet Web 应用且容器里有 Tracer 时注册。spring-web 与 Servlet API 是可选依赖,非 Web 应用引入不会被带上 Web 依赖。
  • 过滤器在调用后续过滤器链之前写头:响应一旦提交,之后设置的头会被静默丢弃。
  • 当前没有活动 span(例如关闭了 HTTP 观测)时不写头,请求照常处理。

不适用的场景 / 已知问题 ​

  1. 默认采样率是 Boot 的 10%。未被采样的请求仍会返回 traceId,但链路系统里查不到;排查偶发问题时要调高 management.tracing.sampling.probability。
  2. 不带 actuator 端点。需要 /actuator/** 健康检查或指标端点时,自行引入 spring-boot-starter-actuator 并收敛暴露范围。
  3. 只带了 OTLP 导出器。要用 Zipkin 等其他协议需自行加依赖。
  4. WebFlux 应用不注册响应头过滤器,目前只支持 Servlet 栈。
  5. 导出到后端没有自动化测试,只在参考应用 ddk-mall 里对着真实的 Collector 和 Tempo 手工验证过。
  6. 和 RocketMQ 一起用需要 0.6.0:更早的版本里 rocketmq-client 带进来的旧版 okio 会让链路导出在运行时失败(NoSuchMethodError: okio.Okio.socket),应用照常启动,只在日志里报错。0.6.0 的 BOM 统一了 okio 的版本。

文章以 CC BY-NC-SA 4.0 授权 · 代码片段以 MIT 授权