未提交的消息不再被消耗

时间:2018-05-22 20:45:59

标签: java apache-kafka

我正在使用Kafka监听器来消费者消息。我启用了手动确认功能。我已经使用Acknowledgment.acknowledge()方法在成功的情况下提交偏移量。如果由于某些API调用失败而导致异常,我还没有提交它。

我有点困惑,因为除非我重新启动我的应用程序,否则未提交的消息不再被消耗掉。我是kafka的新手,所以我确信我错过了一些非常基本的东西,但搜索对此无用。 有人可以解释或指向我正确的来源,我可以知道这里有什么问题吗?

 @KafkaListener(topics = "temp_topic", groupId = "temp-consumer", containerFactory = "tempListenerContainerFactory")
public void receive(ConsumerRecord<?, ?> consumerRecord,
                                   Acknowledgment acknowledgment) {
    try {
        log.info("Consuming message : {} ", consumerRecord.value().toString());
        String message = consumerRecord.value().toString();
         objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
         Payload payload = objectMapper.readValue(message,Payload.class);
         tempService.processEvent(payload);
         log.info("Message: {} successfully consumed",message);
         acknowledgment.acknowledge();
    } catch (Exception e) {
        log.error("Error while listening to kafka event: ", e);
    }
}

提前谢谢。

2 个答案:

答案 0 :(得分:1)

确认不会改变消费者实际阅读的点 它只向一些存储器(带有偏移量的zookeeper或kafka主题)提交偏移量,并且不对消费者跟踪的偏移量进行任何更改 - 例如,您可能不提交当前偏移量并通过在下一个偏移量上设置确认来覆盖它。

有一些方法可以尝试处理失败的消息:

  1. 您可以为特定类型的失败做好准备(例如超时,反序列化错误) - 在侦听器中捕获它们并采取正确的操作(例如,等待/重试或使应用程序失败 - 取决于问题的性质)。
  2. 您可以跳过失败的消息 - 在侦听器中捕获错误,将它们放入存储器以获取失败的消息(请参阅死信队列),然后对它们进行确认。

答案 1 :(得分:1)

我读了一下,发现了一种处理失败消息的方法。 我们制作3个主题

  1. 主要主题
  2. 附加主题
  3. 死主题
  4. 想法是使用主要主题中的消息,如果由于任何原因导致消息失败,请将其推送到旁边主题,在 t < n 次数/ strong>时间间隔。

    如果在副队列中的所有重试之后它失败,那么将其推送到死主题,它将简单地通知(使用电子邮件或任何其他服务)有关失败的信息。

    我不确定这是否是标准,但这是我迄今为止阅读的所有内容中最有意义的。

    如果可以的话,请随意添加或更正。