Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring Kafka@SendTo引发异常:需要KafkaTemplate来支持回复_Spring_Spring Boot_Apache Kafka_Spring Kafka - Fatal编程技术网

Spring Kafka@SendTo引发异常:需要KafkaTemplate来支持回复

Spring Kafka@SendTo引发异常:需要KafkaTemplate来支持回复,spring,spring-boot,apache-kafka,spring-kafka,Spring,Spring Boot,Apache Kafka,Spring Kafka,我正试图得到消费者的结果,根据 基于,只有通过使用@SendTo注释才能做到这一点,因为spring boot“如果上下文中还没有卡夫卡模板,也会自动配置卡夫卡模板。” 但我不能让它工作,我仍然可以 java.lang.IllegalStateException: a KafkaTemplate is required to support replies at org.springframework.util.Assert.state(Assert.java:73) ~[spring

我正试图得到消费者的结果,根据

基于,只有通过使用
@SendTo
注释才能做到这一点,因为spring boot“如果上下文中还没有卡夫卡模板,也会自动配置卡夫卡模板。”

但我不能让它工作,我仍然可以


java.lang.IllegalStateException: a KafkaTemplate is required to support replies
    at org.springframework.util.Assert.state(Assert.java:73) ~[spring-core-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.kafka.config.MethodKafkaListenerEndpoint.createMessageListener(MethodKafkaListenerEndpoint.java:156) 
...
这是我的侦听器方法

@KafkaListener(topics=“t_invoice”)
@发送至(“t_分类账”)
公共列表消费(发票)引发IOException{
//做一些处理
var ledgerCredit=new-LedgerEntry(invoice.getAmount(),“贷方”,0,”;
var-ledgerDebit=new-LedgerEntry(0,”,invoice.getAmount(),“借方”);
返回列表(ledgerCredit、ledgerDebit);
}
我错过了什么

这是我在consumer上唯一的
@配置文件。
消费者和生产者是分离的系统(例如,支付系统向卡夫卡开具发票,我的程序是会计系统,它获取数据并创建分类账分录)

@配置
公共级卡夫卡康菲{
@自动连线
私人卡夫卡财产卡夫卡财产;
@豆子
公共消费者工厂消费者工厂(){
var properties=kafkaProperties.buildConsumerProperties();
properties.put(ConsumerConfig.METADATA_MAX_AGE_CONFIG,“600000”);
返回新的默认卡夫卡消费工厂(属性);
}
@豆子
公共KafkaListenerContainerFactory KafkaListenerContainerFactory(){
var factory=新的ConcurrentKafkaListenerContainerFactory();
setConsumerFactory(consumerFactory());
返回工厂;
}
}
application.yml

spring:
  kafka:
    consumer:
      group-id: default-spring-consumer
      auto-offset-reset: earliest
试错1

如果在运行期间禁用卡夫卡图,或启用调试,则存在以下错误:

org.apache.kafka.common.errors.SerializationException: Can't convert value of class com.accounting.kafkaconsumer.entity.LedgerEntry to class org.apache.kafka.common.serialization.StringSerializer specified in value.serializer
Caused by: java.lang.ClassCastException: class com.accounting.kafkaconsumer.entity.LedgerEntry cannot be cast to class java.lang.String (com.accounting.kafkaconsumer.entity.LedgerEntry is in unnamed module of loader 'app'; java.lang.String is in module java.base of loader 'bootstrap')
    at org.apache.kafka.common.serialization.StringSerializer.serialize(StringSerializer.java:28) ~[kafka-clients-2.0.1.jar:na]
    at org.apache.kafka.common.serialization.ExtendedSerializer$Wrapper.serialize(ExtendedSerializer.java:65) ~[kafka-clients-2.0.1.jar:na]
    at org.apache.kafka.common.serialization.ExtendedSerializer$Wrapper.serialize(ExtendedSerializer.java:55) ~[kafka-clients-2.0.1.jar:na]
...
试错2
如果禁用Kafkanconfig
并使用此签名(返回字符串),它会工作。但这不是预期的,因为我的配置是在
kafkanconfig

@KafkaListener(topics=“t_invoice”)
@发送至(“t_分类账”)
公共字符串消费(发票)引发IOException{
//做一些处理
var listLedger=List.of(ledgerCredit,ledgerDebit);
返回objectMapper.writeValueAsString(listLedger);
}
我认为问题在这里(
kafkanconfig
),因为我创建了
KafkaListenerContainerFactory
的新实例,
replyTemplate
为空。 如何正确设置我的
kafkanconfig

@Bean
公共KafkaListenerContainerFactory KafkaListenerContainerFactory(){
var factory=新的ConcurrentKafkaListenerContainerFactory();
setConsumerFactory(consumerFactory());
返回工厂;
}

如果覆盖Boot的自动配置容器工厂,那么它将不会。。。自动配置,包括应用模板。定义自己的工厂时,您负责对其进行配置。不清楚为什么要覆盖Boot的
kafkaListenerContainerFactory
bean,因为您所做的只是注入消费者工厂。只需删除该
@Bean
并使用Boot。

如果覆盖Boot的
kafkaListenerContainerFactory
请确保设置了回复模板

    @Bean
    public ConcurrentKafkaListenerContainerFactory<String, Object> kafkaListenerContainerFactory(KafkaTemplate<String, Object> kafkaTemplate) {
        ConcurrentKafkaListenerContainerFactory<String, Object> factory =
                new ConcurrentKafkaListenerContainerFactory<>();
        factory.setConsumerFactory(consumerFactory());
        factory.setReplyTemplate(kafkaTemplate); // <============
        return factory;
    }
@Bean
公共并发kafkaListenerContainerFactory kafkaListenerContainerFactory(KafkatTemplate KafkatTemplate){
ConcurrentKafkalistener集装箱工厂=
新的ConcurrentKafkaListenerContainerFactory();
setConsumerFactory(consumerFactory());

factory.setReplyTemplate(kafkaTemplate);//您使用的是哪个版本的Spring Boot?2.1.6.RELEASE。也使用了2.1.5.RELEASE进行了尝试,但都不起作用。更新了关于问题@GaryRussellSo的完整堆栈跟踪和build.gradle文件,还有一些其他问题。请使用--debug运行并检查自动配置报告。还可以尝试进入容器工厂bean定义。如果您不能找出答案,编辑问题以显示所有@Configuration类和属性。出现了一些尝试性错误(我更新了问题),但仍然没有得到令人满意的结果。当然,如果您覆盖Boot的自动配置容器工厂,那么它将不会…自动配置,包括应用模板。当您定义自己的工厂时,您负责对其进行配置。不清楚为什么要覆盖Boot的
kafkaListenerContainerFactory
bean因为你所做的就是注入消费者工厂。只需删除
@Bean
并使用Boot。我的错是,获取一些复制粘贴代码来覆盖
KafkListenerContainerFactory
Bean。谢谢你Garyin,如果我有一个生产者配置,有一个KafkCamessageListenerContainer和一个ConcurrentKafkListenerContainerFactory,both使用consumer properties“ConsumerConfig”工厂的配置,在任何请求下,my Replying KafkatTemplate都会获得kafka回复超时,例外情况是不要对旧答案提出新问题;如果不查看您的设置,就无法推测问题。提出显示代码和配置的新问题。