支持多个消费者的Spring Kafka要求

时间:2020-07-27 03:38:09

标签: spring spring-boot apache-kafka spring-kafka

正如人们期望的那样,它的共同点是希望让不同的消费者以不同的方式反序列化Kafka中的主题。 spring boot autoconfig存在一个已知问题。似乎一旦定义了其他工厂,Spring Kafka或autoconfig就会抱怨不再能够找到合适的消费工厂。有人指出,一种解决方案是在配置中包含类型为(对象,对象)的ConsumerFactory。但是,没有人显示此源代码或澄清是否需要以任何特定方式命名。或者,如果仅将此使用者添加到配置中,则无需关闭自动配置。所有这些都还不清楚。

如果您不熟悉此问题,请阅读https://github.com/spring-projects/spring-boot/issues/19221

在没有问题的地方,定义ConsumerFactory并将其添加到配置中的某个位置。有人可以更精确一点吗?

  1. 确切显示如何定义ConsumerFactory,以使Spring boot autoconfig不会出错。
  2. 请问是否需要关闭自动配置?
  3. 说明是否需要使用特殊方式来命名Consumer Factory。

1 个答案:

答案 0 :(得分:0)

最简单的解决方案是坚持使用Boot的自动配置,并在@KafkaListener本身上覆盖反序列化器...

@SpringBootApplication
public class So63108344Application {

    public static void main(String[] args) {
        SpringApplication.run(So63108344Application.class, args);
    }

    @KafkaListener(id = "so63108344-1", topics = "so63108344-1")
    public void listen1(String in) {
        System.out.println(in);
    }

    @KafkaListener(id = "so63108344-2", topics = "so63108344-2", properties =
            ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG +
                "=org.apache.kafka.common.serialization.ByteArrayDeserializer")
    public void listen2(byte[] in) {
        System.out.println(in);
    }

    @Bean
    public NewTopic topic1() {
        return TopicBuilder.name("so63108344-1").partitions(1).replicas(1).build();
    }

    @Bean
    public NewTopic topic2() {
        return TopicBuilder.name("so63108344-2").partitions(1).replicas(1).build();
    }

}

要进行更高级的容器自定义(或者如果您不想污染@KafkaListener,则可以使用ContainerCustomizer ...

@Component
class Customizer {
    
    public Customizer(ConcurrentKafkaListenerContainerFactory<?, ?> factory) {
        factory.setContainerCustomizer(container -> {
            if (container.getGroupId().equals("so63108344-2")) {
                container.getContainerProperties().setAckMode(AckMode.MANUAL_IMMEDIATE);
                container.getContainerProperties().getKafkaConsumerProperties()
                    .setProperty(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.ByteArrayDeserializer");
            }
        });
    }
    
}