使用“@AutoConfigureAfter(TraceAutoConfiguration.class)”时缺少 bean 'zipkin2.reporter.Sender'
Missing bean 'zipkin2.reporter.Sender' when using `@AutoConfigureAfter(TraceAutoConfiguration.class)`
TLDR:
- 在此处复制项目:https://github.com/snussbaumer/zipkin-app-wont-start-repo
- 我想使用 Zipkin Kafka Sender
- 在
TraceAutoConfiguration
来自 Sleuth 之后,我还需要一段自动配置到 运行
- 如果我使用
@AutoConfigureAfter
,应用程序不会启动并失败并显示消息 No qualifying bean of type 'zipkin2.reporter.Sender' available
更多详情:
我正在尝试创建一个自定义 Sleuth 检测服务,该服务在没有可用跟踪时也可以工作。这是服务接口的真正简化版本:
public interface SomeService {
String decorate(String value);
}
然后我创建一个自动配置(因为这段代码在一个单独的模块中,被许多项目使用):
@Configuration
@AutoConfigureAfter(name = "org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration")
@Slf4j
public class TestAutoConfiguration {
@ConditionalOnBean(type = "brave.Tracer")
@Configuration
public static class TracedConfiguration {
@Bean
public SomeService someService(Tracer tracer) {
log.info("Create traced SomeService");
return value -> value + " [" + tracer.currentSpan().toString() + "]";
}
}
@ConditionalOnMissingBean(type = "brave.Tracer")
@Configuration
public static class NoTracedConfiguration {
@Bean
public SomeService someService() {
log.info("Create not traced SomeService");
return value -> value + " [not-traced]";
}
}
}
这个想法实际上是在没有 Tracer 可用时提供一种 Noop 版本的服务。
然后我像往常一样在 spring.factories 文件中声明自动配置。
这是我想要的应用程序 运行 :
@SpringBootApplication
@RestController
@Slf4j
public class ReproApplication {
@Autowired
private SomeService someService;
@GetMapping("/test")
public String test() {
log.info("Test Endpoint called, check TraceId/SpanId/ParentSpanId in log");
return someService.decorate("hello world") + "\n";
}
public static void main(String[] args) {
SpringApplication.run(ReproApplication.class, args);
}
}
对于所有这些,我想使用 Zipkin 和 KafkaSpanReporter。所以我的 application.properties 看起来像这样:
spring.application.name=repro
server.port=8080
spring.kafka.bootstrapServers=kafka:9092
spring.sleuth.sampler.probability=1.0
spring.zipkin.sender.type=kafka
logging.level.org.springframework.boot.autoconfigure=DEBUG
和我的 (t运行cated) pom.xml 像这样:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-kafka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
</dependency>
</dependencies>
当我尝试 运行 此代码时出现错误:
No qualifying bean of type 'zipkin2.reporter.Sender' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
如果我查看配置报告,我会看到:
Parameter 2 of method reporter in org.springframework.cloud.sleuth.zipkin2.ZipkinAutoConfiguration required a bean of type 'zipkin2.reporter.Sender' that could not be found.
- Bean method 'kafkaSender' not loaded because @ConditionalOnBean (types: org.springframework.boot.autoconfigure.kafka.KafkaProperties; SearchStrategy: all) did not find any beans of type org.springframework.boot.autoconfigure.kafka.KafkaProperties
这很奇怪,因为 KafkaAutoConfiguration
上有一个 @EnableConfigurationProperties(KafkaProperties.class)
,配置报告清楚地显示:
KafkaAutoConfiguration matched:
- @ConditionalOnClass found required class 'org.springframework.kafka.core.KafkaTemplate'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
更奇怪的是,如果我在我的 AutoConfiguration 中删除 @AutoConfigureAfter(name = "org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration")
,服务会正常启动 => 但是我得到了我的 bean 的 NoTracedConfiguration
风味,所以 Tracer
可能还没有配置。
我该怎么做才能解决这个问题?
终于成功删除 @AutoConfigureAfter
、@ConditionalOnBean
和 @ConditionalOnMissingBean
,改用 @ConditionalOnClass
、@ConditionalOnMissingClass
并复制其他 @Conditionals
来自 TraceAutoConfiguration
。不是很好,但至少可以工作。
TLDR:
- 在此处复制项目:https://github.com/snussbaumer/zipkin-app-wont-start-repo
- 我想使用 Zipkin Kafka Sender
- 在
TraceAutoConfiguration
来自 Sleuth 之后,我还需要一段自动配置到 运行
- 如果我使用
@AutoConfigureAfter
,应用程序不会启动并失败并显示消息No qualifying bean of type 'zipkin2.reporter.Sender' available
更多详情:
我正在尝试创建一个自定义 Sleuth 检测服务,该服务在没有可用跟踪时也可以工作。这是服务接口的真正简化版本:
public interface SomeService {
String decorate(String value);
}
然后我创建一个自动配置(因为这段代码在一个单独的模块中,被许多项目使用):
@Configuration
@AutoConfigureAfter(name = "org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration")
@Slf4j
public class TestAutoConfiguration {
@ConditionalOnBean(type = "brave.Tracer")
@Configuration
public static class TracedConfiguration {
@Bean
public SomeService someService(Tracer tracer) {
log.info("Create traced SomeService");
return value -> value + " [" + tracer.currentSpan().toString() + "]";
}
}
@ConditionalOnMissingBean(type = "brave.Tracer")
@Configuration
public static class NoTracedConfiguration {
@Bean
public SomeService someService() {
log.info("Create not traced SomeService");
return value -> value + " [not-traced]";
}
}
}
这个想法实际上是在没有 Tracer 可用时提供一种 Noop 版本的服务。
然后我像往常一样在 spring.factories 文件中声明自动配置。
这是我想要的应用程序 运行 :
@SpringBootApplication
@RestController
@Slf4j
public class ReproApplication {
@Autowired
private SomeService someService;
@GetMapping("/test")
public String test() {
log.info("Test Endpoint called, check TraceId/SpanId/ParentSpanId in log");
return someService.decorate("hello world") + "\n";
}
public static void main(String[] args) {
SpringApplication.run(ReproApplication.class, args);
}
}
对于所有这些,我想使用 Zipkin 和 KafkaSpanReporter。所以我的 application.properties 看起来像这样:
spring.application.name=repro
server.port=8080
spring.kafka.bootstrapServers=kafka:9092
spring.sleuth.sampler.probability=1.0
spring.zipkin.sender.type=kafka
logging.level.org.springframework.boot.autoconfigure=DEBUG
和我的 (t运行cated) pom.xml 像这样:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-kafka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
</dependency>
</dependencies>
当我尝试 运行 此代码时出现错误:
No qualifying bean of type 'zipkin2.reporter.Sender' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
如果我查看配置报告,我会看到:
Parameter 2 of method reporter in org.springframework.cloud.sleuth.zipkin2.ZipkinAutoConfiguration required a bean of type 'zipkin2.reporter.Sender' that could not be found.
- Bean method 'kafkaSender' not loaded because @ConditionalOnBean (types: org.springframework.boot.autoconfigure.kafka.KafkaProperties; SearchStrategy: all) did not find any beans of type org.springframework.boot.autoconfigure.kafka.KafkaProperties
这很奇怪,因为 KafkaAutoConfiguration
上有一个 @EnableConfigurationProperties(KafkaProperties.class)
,配置报告清楚地显示:
KafkaAutoConfiguration matched:
- @ConditionalOnClass found required class 'org.springframework.kafka.core.KafkaTemplate'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
更奇怪的是,如果我在我的 AutoConfiguration 中删除 @AutoConfigureAfter(name = "org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration")
,服务会正常启动 => 但是我得到了我的 bean 的 NoTracedConfiguration
风味,所以 Tracer
可能还没有配置。
我该怎么做才能解决这个问题?
终于成功删除 @AutoConfigureAfter
、@ConditionalOnBean
和 @ConditionalOnMissingBean
,改用 @ConditionalOnClass
、@ConditionalOnMissingClass
并复制其他 @Conditionals
来自 TraceAutoConfiguration
。不是很好,但至少可以工作。