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

SpringBoot 3集成测试中Zipkin追踪信息无法收集问题求助

问题分析与解决方案

1. 容器网络访问错误

你的Spring Boot测试进程和Zipkin容器不在同一个网络上下文里,配置中用localhost指向的是测试进程所在的主机/进程,而非Zipkin容器。即便给Zipkin容器加了网络别名zipkin,但配置未正确使用这个别名,导致应用无法将追踪数据发送到Zipkin服务。

修复方法:
修改@DynamicPropertySource,用容器网络别名zipkin替代localhost,直接访问容器内部的9411端口(无需用主机映射端口):

@DynamicPropertySource
static void zipkinProperties(DynamicPropertyRegistry registry) {
    registry.add("spring.zipkin.baseUrl", () -> "http://zipkin:9411");
    registry.add("management.zipkin.tracing.endpoint", () -> "http://zipkin:9411/api/v2/spans");
}

因为两者处于Testcontainers的共享网络中,通过别名即可直接通信,不用绕主机映射端口。

2. 依赖版本兼容问题

你手动指定了Micrometer和Zipkin Reporter的版本,可能和Spring Boot 3.1.3的依赖管理不兼容,导致追踪链路无法正常工作。

修复方法:
移除pom.xml中手动指定的版本号,让Spring Boot自动管理兼容版本:

<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-tracing-bridge-brave</artifactId>
    <!-- 移除手动版本号 -->
</dependency>
<dependency>
    <groupId>io.zipkin.reporter2</groupId>
    <artifactId>zipkin-reporter-brave</artifactId>
    <!-- 移除手动版本号 -->
</dependency>

3. 异步上报的时序问题

Zipkin的追踪数据是异步上报的,你在发送请求后立即查询Zipkin,此时数据可能还未完成上报。现有代码的sleep放在断言之后,完全起不到等待作用。

修复方法:
调整等待逻辑到查询Zipkin之前,且无需过长等待:

@Test
void testRestEndpoint() {
    RestTemplate restTemplate = new RestTemplate();
    // 发送测试请求
    IntStream.rangeClosed(0,99).forEach(i ->{
        restTemplate.getForObject("http://localhost:%s/status".formatted(port), String.class);
    });
    String status = restTemplate.getForObject("http://localhost:%s/status".formatted(port), String.class);
    Assertions.assertEquals("OK", status);
    
    // 等待异步上报完成(10秒足够)
    sleep(10);
    
    // 再查询Zipkin验证数据
    String zipkinResult = restTemplate.getForObject("http://localhost:%s/api/v2/spans?serviceName=spring-micrometer-tracing-demo".formatted(getPort()), String.class);
    Assertions.assertFalse("[]".equals(zipkinResult));
}

4. 容器启动等待条件优化

当前用/api/v2/spans?serviceName=anything作为启动完成的判断条件,但这个查询接口返回200不代表Zipkin已经准备好接收追踪数据。

修复方法:
改用Zipkin的健康检查端点作为等待条件:

static GenericContainer<?> zipkinContainer = new GenericContainer<>("openzipkin/zipkin:2.24-arm64")
        .withReuse(false)
        .withExposedPorts(9411)
        .waitingFor(Wait.forHttp("/health").forStatusCode(200).withStartupTimeout(Duration.of(2, ChronoUnit.MINUTES)))
        .withNetwork(Network.SHARED)
        .withNetworkAliases("zipkin");

健康端点返回200说明Zipkin服务已完全启动,可正常接收追踪数据。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 12:17:23