You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Quarkus Netty(Vert.x)集成X-Ray追踪DynamoDB请求异常排查

解决Quarkus Reactive(Netty)中X-Ray追踪DynamoDB调用的问题

问题根源分析

你当前的核心问题是混合使用了AWS X-Ray原生SDK与Quarkus OpenTelemetry(OTel)两套追踪体系:

  • Quarkus的DynamoDB扩展通过OTel生成追踪数据
  • 你配置的TracingInterceptor是基于X-Ray自身的上下文体系,与OTel上下文不共享,导致DynamoDB子段无法找到父Span;添加Vert.x Handler后异常消失,但因体系冲突仍无法生成关联的DynamoDB追踪节点。

分步解决方案

1. 统一追踪方案:移除X-Ray SDK依赖与冲突配置

删除与X-Ray原生SDK相关的内容,完全基于Quarkus OTel体系实现追踪:

  • 移除Gradle依赖中的com.amazonaws:aws-xray-recorder-sdk-aws-sdk-v2
  • 删除application.properties中的quarkus.dynamodb.interceptors=com.amazonaws.xray.interceptors.TracingInterceptor
  • 保留quarkus.dynamodb.telemetry.enabled=true(Quarkus会自动通过OTel追踪DynamoDB调用)

2. 实现Vert.x入站请求的根Span追踪(替代Servlet Filter)

Quarkus Reactive基于Vert.x,需通过OTel为所有入站请求创建根Span,确保DynamoDB调用能关联到父追踪上下文:

import io.opentelemetry.api.trace.Span
import io.opentelemetry.api.trace.Tracer
import io.opentelemetry.context.Context
import io.opentelemetry.context.Scope
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
import io.vertx.ext.web.RoutingContext
import jakarta.enterprise.context.ApplicationScoped
import jakarta.inject.Inject

@ApplicationScoped
class TracingHandler {

    @Inject
    lateinit var tracer: Tracer

    fun handle(rc: RoutingContext) {
        val request = rc.request()
        val spanName = "${request.method()} ${request.path()}"
        
        // 创建根Span并填充HTTP语义属性
        val span = tracer.spanBuilder(spanName)
            .setAttribute(SemanticAttributes.HTTP_METHOD, request.method().name())
            .setAttribute(SemanticAttributes.HTTP_URL, request.absoluteURI())
            .setAttribute(SemanticAttributes.HTTP_SCHEME, request.scheme())
            .startSpan()

        try {
            // 将Span绑定到当前上下文
            Context.current().with(span).makeCurrent().use { _: Scope ->
                // 请求结束时关闭Span并记录状态码
                rc.addEndHandler { _ ->
                    span.setAttribute(SemanticAttributes.HTTP_STATUS_CODE, rc.response().statusCode())
                    span.end()
                }
                rc.next()
            }
        } catch (e: Exception) {
            span.recordException(e)
            span.setAttribute(SemanticAttributes.HTTP_STATUS_CODE, 500)
            span.end()
            throw e
        }
    }
}

注册该Handler到所有路由(确保优先级最高):

import io.quarkus.vertx.web.RouteFilter
import jakarta.inject.Inject

class RoutesConfig {

    @Inject
    lateinit var tracingHandler: TracingHandler

    @RouteFilter(100)
    fun applyTracingFilter(rc: RoutingContext) {
        tracingHandler.handle(rc)
    }
}

3. 验证OTEL Collector配置

确保ECS中的OTEL Collector正确将OTel Span转换为X-Ray格式并发送,检查ecs-xray.yaml配置:

receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318

processors:
  batch:
  awsxray:

exporters:
  awsxray:
    region: eu-central-1

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [batch, awsxray]
      exporters: [awsxray]

你的IAM权限配置已经满足要求(包含xray:PutTraceSegments和xray:PutTelemetryRecords),无需修改。

4. 调试与验证

开启OTel调试日志,确认DynamoDB Span是否生成:

quarkus.log.category."io.opentelemetry".level=DEBUG
quarkus.log.category."io.quarkus.opentelemetry".level=DEBUG

查看日志中是否存在DynamoDB相关的Span创建、导出记录,同时检查X-Ray控制台是否生成完整的追踪链路。


内容的提问来源于stack exchange,提问作者jDudek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 02:05:33