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.* |
| 导出到 OTLP | opentelemetry-exporter-otlp,management.opentelemetry.tracing.export.otlp.* |
| 日志里的 traceId / spanId | Spring 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/tracesSpring Boot 4.1 把 OTLP 链路导出的配置移到了 management.opentelemetry.tracing.export.otlp.*,原来的 management.otlp.tracing.* 已标记为过时。
配置项
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
ddk.tracer.response-header.enabled | boolean | true | 是否把 traceId 写进响应头 |
ddk.tracer.response-header.name | String | X-Trace-Id | 响应头名称 |
ddk.tracer.async-propagation.enabled | boolean | true | 链路上下文是否跟随任务进入 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 观测)时不写头,请求照常处理。
不适用的场景 / 已知问题
- 默认采样率是 Boot 的 10%。未被采样的请求仍会返回 traceId,但链路系统里查不到;排查偶发问题时要调高
management.tracing.sampling.probability。 - 不带 actuator 端点。需要
/actuator/**健康检查或指标端点时,自行引入spring-boot-starter-actuator并收敛暴露范围。 - 只带了 OTLP 导出器。要用 Zipkin 等其他协议需自行加依赖。
- WebFlux 应用不注册响应头过滤器,目前只支持 Servlet 栈。
- 导出到后端没有自动化测试,只在参考应用
ddk-mall里对着真实的 Collector 和 Tempo 手工验证过。 - 和 RocketMQ 一起用需要 0.6.0:更早的版本里
rocketmq-client带进来的旧版 okio 会让链路导出在运行时失败(NoSuchMethodError: okio.Okio.socket),应用照常启动,只在日志里报错。0.6.0 的 BOM 统一了 okio 的版本。