如何在Apache Kafka中处理异常和消息重新处理

时间:2020-01-24 17:03:39

标签: apache-kafka

我有一个kafka集群。只有一个主题,对于这个主题,3个不同的消费者组从该主题获取相同的消息,并根据其自身的逻辑进行不同的处理。

为多个消费者群体创建相同主题是否有问题?

由于我正在尝试实现异常主题并尝试重新处理此消息,所以我对此表示怀疑。 假设我在主题A中有消息“秘密”。 我所有的三个消费群体都收到了“秘密”消息。 我的两个消费群体已成功完成邮件的处理。 但是因为我的一个消费者组无法处理该消息。

所以我将邮件保留在主题“ failed_topic”中。 我想尝试为失败的使用者处理此消息。但是,如果我将此消息保留在我的实际主题A中,则其他两个消费者组将第二次处理此消息。

有人可以让我知道如何为这种情况实现完美的重新处理吗?

2 个答案:

答案 0 :(得分:0)

为多个消费者群体创建相同主题是否有问题?

一点都不

如果我将此消息保留在实际主题A中,则其他两个消费者组将第二次处理此消息。

确切地说,您将创建一个循环(第三组将失败,放回去,2接受它,第三组再次失败,依此类推,等等)

基本上,您是在询问“死信队列”,这将是每个消费者组的特定主题 。 Kafka可以容纳成千上万的主题,因此在您的用例中这不应该成为问题。

答案 1 :(得分:0)

首先,在卡夫卡,每个消费者组对于订阅的每个主题分区都有自己的偏移量,这些偏移量由消费者组单独管理。因此,一个消费者群体的失败不会影响其他消费者群体。

您可以使用此cli命令检查使用者组的当前偏移量:

bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --describe --group my-group

为多个使用者创建相同主题是否有问题 组

不。没有问题。实际上,这是基于主题的发布者/订阅者模式的正常行为。


要实现后处理逻辑,需要考虑一些重要点:

  • 即使您正在重新处理poll(),也应继续调用poll() 信息。否则在max.poll.interval.ms之后,您的消费者 将被视为死亡并被撤销。
  • 通过调用poll(),您将收到您的消费群体尚未收到的消息 还没读因此,当您poll()时,您会收到最多 max.poll.records再次轮询()时,您会得到 下一组消息。因此,对于重新处理失败的消息,您需要 调用搜寻方法。

public void seek(TopicPartition分区,长偏移量):覆盖 使用者将在下一次轮询(超时)时使用的提取偏移量

  • 理想情况下,您在消费者组中的消费者数量应为 等于已订阅主题的分区数。卡夫卡将 请注意将分区平均分配给使用者。 (一个分区 每个消费者)但即使这个条件也可以满足 开始,一段时间后,消费者可能会死亡,Kafka可能会分配 一个消费者可以使用多个分区。这可能会导致一些问题。假设您的使用者负责两个分区,当poll()时,您将从这两个分区中获取消息,而当消息无法使用时,您应该搜索所有已分配的分区(不仅仅是一个失败的消息来自)。否则,您可能会跳过一些消息。

让我们尝试使用以下信息来编写一些伪代码以实现异常情况下的重新处理逻辑:

public void consumeLoop() {
    while (true) {
        currentRecord = consumer.poll(); //max.poll.records = 1
        if (currentRecord != null) {
            try {
                processMessage(currentRecord);
            } catch (Exception e) {
                consumer.seek(new TopicPartition(currentRecord.topic(), currentRecord.partition()), currentRecord.offset());
                continue;
            }
            consumer.commitSync(Collections.singletonMap(topicPartition, new OffsetAndMetadata(currentRecord.offset() + 1)));
        }
    }
}

有关代码的注释:

  • max.poll.records设置为一个,以简化查找过程。
  • 在每个异常中,我们都进行搜索和轮询以再次获得相同的消息。 (我们 必须进行投票才能被卡夫卡视为还活着)
  • 禁用了auto.commit