使用 SpringBootTest 时如何在控制器中使用 span 初始化默认跟踪上下文

How to init a default trace context with span in controller when using SpringBootTest

我正在从 Spring Boot 1.5.21 转移到 2.2.5,在此过程中也从 spring-boot-cloud 版本 Edgware.SR6 转移到 Hoxton.SR3 .此举迫使我放弃侦探自己的 tracer/span 模型实施,并接受来自 brave 的新模型。但是,我的控制器集成测试有问题。

我有一个名为 Edge 的微服务和一个名为 EdgeApplication 的主要 class,我使用 Spock 作为测试框架。 我的代码包括以下测试 class:

@ContextConfiguration(classes = EdgeApplication.class)
@SpringBootTest(classes = EdgeApplication.class)
@ActiveProfiles(profiles = ["test"])
@AutoConfigureMockMvc
class VerificationCodeControllerSpecIT extends Specification {

  @Autowired
  MockMvc mockMvc

  def setup() {
     mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build()
  }

  def "Generate change password verification code"() {
    // Some code calling a PrincipalController via mockMvc.perform()
  }
}

以前,在 Spring Boot 1.5.21 中,当调用到达 PrincipalController 时,会初始化带有跨度的默认跟踪上下文。现在,在 Spring Boot 2 中,情况并非如此。我必须强调,PrincipalController 中缺少上下文只发生在测试代码中,而不是真正的 运行 微服务。

为什么这种行为发生了变化?我该如何恢复旧的行为,即在调用控制器时有一个带有 span 的默认跟踪上下文?

我添加了一个演示项目: Demo 您将能够 运行 集成测试并在调试中看到在控制器中 tracer.currentSpan() 为空(同时在正常项目 运行 中包含一个值)

如果它与 Spring 安全相关,也许您应该使用 https://github.com/spring-projects/spring-security/blob/5.3.2.RELEASE/test/src/main/java/org/springframework/security/test/web/servlet/setup/SecurityMockMvcConfigurers.java。示例:

MockMvcBuilders.webAppContextSetup(this.wac)
   .apply(SecurityMockMvcConfigurers.springSecurity())
   .build();

在 Spring Boot 1.5.21 中,spring-cloud-sleuth 的最新支持版本是 1.3.6.RELEASE.

在旧版本中,Sleuth 曾经有拦截器:'TraceHandlerInterceptor' 当 Servlet 调度程序触发此拦截器时创建一个 span。

虽然 运行 您的 Spring 版本 1.5.21 启动测试触发上述拦截器的 MockMvc init TestDispatcherServlet。

作为与 Brave 对齐的 HTTP 工具的一部分,此拦截器已被删除。

使用 MockMvc 时,有必要显式配置过滤器链。 你的 MockMvc 缺少 TracingFilter