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

OpenTelemetry追踪数据仅在服务重启时上报,求排查建议

问题分析与解决方案

你的Traces仅在应用重启时上报,核心原因是BatchSpanProcessor的批量导出策略未合理配置,且缺少主动触发导出的逻辑,同时需要确认Span是否被正确结束。以下是具体问题点和修复方案:

1. BatchSpanProcessor默认配置导致延迟上报

你使用的BatchSpanProcessor默认采用保守的批量策略:

  • 默认导出间隔为5秒
  • 默认队列大小为2048条
  • 仅当队列填满或到达间隔时间时,才会批量导出Span

如果你的请求量不大,Span无法填满队列且没到间隔时间,就会一直积压在内存中,直到应用重启时SDK销毁才会强制flush所有积压的Span。

修复:调整BatchSpanProcessor的导出策略

修改SpanProcessor的构建代码,缩短导出间隔并减小队列阈值,让Span能更快被导出:

BatchSpanProcessor.builder(exporter)
        .setScheduleDelay(Duration.ofMillis(1000)) // 每1秒尝试一次导出
        .setMaxQueueSize(100) // 队列累计100条Span就触发导出
        .setMaxExportBatchSize(50) // 每次最多导出50条
        .build()

2. 缺少应用关闭时的主动Flush逻辑

即使调整了批量策略,仍可能有少量Span在应用正常退出时积压。需要添加JVM关闭钩子,主动触发TracerProvider的shutdown操作,强制导出所有未发送的Span:

// 注册JVM关闭钩子,确保应用退出时完成Span导出
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
    tracerProvider.shutdown();
    try {
        // 等待最多5秒,确保导出完成
        tracerProvider.awaitShutdown(Duration.ofSeconds(5));
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}));

3. 确认Span被正确结束

如果业务代码中创建了Span但未调用span.end(),Span会一直处于未完成状态,BatchSpanProcessor不会导出未结束的Span,只有应用重启时才会被强制清理导出。

检查你的业务代码,确保每个Span都在逻辑完成后调用end():

// 示例:正确的Span使用方式
Tracer tracer = openTelemetry.getTracer("your-tracer-name");
Span span = tracer.spanBuilder("request-processing").startSpan();
try (Scope scope = span.makeCurrent()) {
    // 处理请求的业务逻辑
} finally {
    // 必须调用end()标记Span完成
    span.end();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 21:49:53