Отсутствует bean-компонент zipkin2.reporter.Sender при использовании @AutoConfigureAfter(TraceAutoConfiguration.class)`

TLDR:

  • Воспроизведение проекта здесь: https://github.com/snussbaumer/zipkin-app-wont-start-repo
  • Я хочу использовать Zipkin Kafka Sender
  • Мне также нужен кусок AutoConfiguration для запуска после 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]";
        }
    }
}

Идея состоит в том, чтобы иметь своего рода Noop-версию сервиса, когда Tracer недоступен.

Затем я объявляю автоконфигурацию в файле 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

и мой (усеченный) 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

Это странно, потому что есть @EnableConfigurationProperties(KafkaProperties.class) на KafkaAutoConfiguration и отчет о конфигурации ясно показывает:

KafkaAutoConfiguration matched:
  - @ConditionalOnClass found required class 'org.springframework.kafka.core.KafkaTemplate'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)

Что еще более странно, так это то, что если я удалю @AutoConfigureAfter(name = "org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration") в своей автоконфигурации, служба запустится правильно =>, но я получу вариант NoTracedConfiguration моего компонента, поэтому Tracer, вероятно, еще не настроен.

Что я могу сделать, чтобы решить эту проблему?


person Sébastien Nussbaumer    schedule 24.09.2018    source источник


Ответы (1)


Наконец-то получилось удалить @AutoConfigureAfter, @CondtionnalOnBean и @ConditionnalOnMissingBean, используя вместо них @ConditionalOnClass, @ConditionnalOnMissingClass и воспроизведя другие @Conditionnals из TraceAutoConfiguration. Не супер, но по крайней мере работает.

person Sébastien Nussbaumer    schedule 25.09.2018
comment
Та же проблема в версии 2.1.0.RELEASE. Есть ли гораздо лучшее действительное решение? - person İlker Korkut; 27.01.2019