【问题标题】:Infinite loop in Spring Kafka producer when sending message to an Invalid Topic向无效主题发送消息时,Spring Kafka 生产者中的无限循环
【发布时间】:2021-08-13 21:54:38
【问题描述】:

我正在开发一个 Spring Boot 应用程序。该应用程序充当 Kafka 生产者,其中生产/发布消息不是很重要。我正在使用 spring-kafka 依赖项和 Kafka 的以下配置

    @Bean
public ProducerFactory<String, Object> producerFactory() {
    Map<String, Object> configProps = new HashMap<>();

    configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaConfig.getKafkaBrokers());
    configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
    configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class);
    configProps.put(ProducerConfig.RETRIES_CONFIG, 3);
    
    return new DefaultKafkaProducerFactory<>(configProps);
}

@Bean
public KafkaTemplate<String, Object> kafkaTemplate(ProducerFactory<String, Object> producerFactory) {
    return new KafkaTemplate<>(producerFactory);
}

当我向不存在的主题发送消息时。我的应用程序显示以下日志

17:18:45.187 [kafka-producer-network-thread | producer-1] WARN  org.apache.kafka.clients.NetworkClient - [] [Producer clientId=producer-1] Error while fetching metadata with correlation id 3 : {aksubd=UNKNOWN_TOPIC_OR_PARTITION}
17:18:45.347 [kafka-producer-network-thread | producer-1] WARN  org.apache.kafka.clients.NetworkClient - [] [Producer clientId=producer-1] Error while fetching metadata with correlation id 4 : {aksubd=UNKNOWN_TOPIC_OR_PARTITION}
17:18:45.522 [kafka-producer-network-thread | producer-1] WARN  org.apache.kafka.clients.NetworkClient - [] [Producer clientId=producer-1] Error while fetching metadata with correlation id 5 : {aksubd=UNKNOWN_TOPIC_OR_PARTITION}
17:18:45.687 [kafka-producer-network-thread | producer-1] WARN  org.apache.kafka.clients.NetworkClient - [] [Producer clientId=producer-1] Error while fetching metadata with correlation id 6 : {aksubd=UNKNOWN_TOPIC_OR_PARTITION}
17:18:45.864 [kafka-producer-network-thread | producer-1] WARN  org.apache.kafka.clients.NetworkClient - [] [Producer clientId=producer-1] Error while fetching metadata with correlation id 7 : {aksubd=UNKNOWN_TOPIC_OR_PARTITION}
17:18:46.035 [kafka-producer-network-thread | producer-1] WARN  org.apache.kafka.clients.NetworkClient - [] [Producer clientId=producer-1] Error while fetching metadata with correlation id 8 : {aksubd=UNKNOWN_TOPIC_OR_PARTITION}
17:18:46.203 [kafka-producer-network-thread | producer-1] WARN  org.apache.kafka.clients.NetworkClient - [] [Producer clientId=producer-1] Error while fetching metadata with correlation id 9 : {aksubd=UNKNOWN_TOPIC_OR_PARTITION}
17:18:46.378 [kafka-producer-network-thread | producer-1] WARN  org.apache.kafka.clients.NetworkClient - [] [Producer clientId=producer-1] Error while fetching metadata with correlation id 10 : {aksubd=UNKNOWN_TOPIC_OR_PARTITION}
17:18:46.546 [kafka-producer-network-thread | producer-1] WARN  org.apache.kafka.clients.NetworkClient - [] [Producer clientId=producer-1] Error while fetching metadata with correlation id 11 : {aksubd=UNKNOWN_TOPIC_OR_PARTITION}
17:18:46.715 [kafka-producer-network-thread | producer-1] WARN  org.apache.kafka.clients.NetworkClient - [] [Producer clientId=producer-1] Error while fetching metadata with correlation id 12 : {aksubd=UNKNOWN_TOPIC_OR_PARTITION}
17:18:46.888 [kafka-producer-network-thread | producer-1] WARN  org.apache.kafka.clients.NetworkClient - [] [Producer clientId=producer-1] Error while fetching metadata with correlation id 13 : {aksubd=UNKNOWN_TOPIC_OR_PARTITION}
17:18:47.055 [kafka-producer-network-thread | producer-1] WARN  org.apache.kafka.clients.NetworkClient - [] [Producer clientId=producer-1] Error while fetching metadata with correlation id 14 : {aksubd=UNKNOWN_TOPIC_OR_PARTITION}
17:18:47.233 [kafka-producer-network-thread | producer-1] WARN  org.apache.kafka.clients.NetworkClient - [] [Producer clientId=producer-1] Error while fetching metadata with correlation id 15 : {aksubd=UNKNOWN_TOPIC_OR_PARTITION}

日志处于无限循环中(我只显示开始的几个日志)。我故意给出一个不存在的无效主题“aksubd”只是为了证明这个问题。我是 kafka 的新手,想知道这是否是 Kafka 的正常行为,因为这可能会写入不必要的日志。我不希望应用程序无限记录。有没有办法在配置中设置一定数量的重试后停止,然后在控制台上抛出错误?注意:我尝试将重试次数设置为 3,但没有成功。

【问题讨论】:

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


    【解决方案1】:

    确实,这是预期的行为。

    如果您在代理上有auto.create.topics.enable=true,那么主题将在生产者请求时创建,但建议禁用此功能,因为客户端可能会输入主题名称,然后想知道他们的数据实际上在哪里结束。尽管名称如此,retries 并不适用于元数据请求,仅适用于生产者批处理请求。

    如果您想事先检查某个主题,请在生成主题之前使用 AdminClient 对其进行描述。

    【讨论】:

    • 我的用例中只有 1 个主题是从外部配置设置的。我只想知道是否有办法让 kafkaTemplate.send() 在配置中设置无效主题名称时失败,而不是尝试无限尝试发送消息。如果失败,我可以处理失败,但无限打印日志可能会使应用程序崩溃。就像即使有人错误地从外部配置中设置了无效的主题名称,应用程序也应该毫无问题地运行。顺便说一句,kafkaTemplate.send() 位于带有 @Async 注释的单独方法中。
    • 我不知道在这种情况下让 spring-kafka 失败的方法。就像我说过的,使用 AdminClient 来验证主题或使用主题 @Bean 从您的配置中实际创建它。除非您没有正确使用滚动文件附加程序,否则单独的日志不应使应用程序崩溃
    • 获取元数据是一个阻塞操作;默认情况下,kafkaTemplate.send() 最终会在 60 秒后失败。您可以通过减少生产者 max.block.ms 属性的默认值 60000 来加速失败。kafka.apache.org/documentation/#producerconfigs_max.block.ms
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-27
    • 2019-05-20
    • 2016-01-01
    • 1970-01-01
    • 2017-12-15
    • 1970-01-01
    相关资源
    最近更新 更多