繁体   English   中英

处理Kafka消息时,如何处理session超时?

[英]How to handle session timeout while processing Kafka messages?

我正在标准处理循环中处理来自 Kafka 的消息:

  while (true) {
     ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));
     for (ConsumerRecord<String, String> record : records) {
         processMessage(record);
     }
  }

如果我的 Kafka Consumer 在处理记录时超时,我该怎么办? 我的意思是超时由属性session.timeout.ms控制 当发生这种情况时,我的消费者应该停止处理记录,因为它会丢失其分区并且它处理的记录可能已经被另一个消费者处理过。 如果原始消费者将一些处理结果写入数据库,它可能会覆盖在我的原始消费者超时后获得分区的“新”消费者产生的记录。

我知道 ConsumerRebalanceListener,但根据我的理解,它的 onPartitionsLost 方法只会在我从消费者调用 poll 方法后调用。 因此,这无助于停止我从上次轮询中收到的那批记录的处理循环。

我希望心跳线程可以通知我它无法联系代理,并且我们在消费者中有一个 session 超时,但似乎没有那样的东西......我错过了什么吗?

添加这个作为答案,因为它在评论中太长了。

Kafka有几种方法可以用来处理消息

  • 最多一次;
  • 至少一次;
  • 就一次。

您描述的是您想将 kafka 用作 exactly once 语义(顺便说一下,这是使用 kafka 的最不常见的方式)。 生产者也需要很好地发挥作用,因为默认情况下 kafka 可以多次产生相同的消息。

构建使用至少一次机制的服务更为常见,通过这种方式,您可以多次接收(或处理)相同的消息,但您需要有一种方法来删除它们(这与幂等性背后的想法相同) http API)。 您需要在消息中包含一些唯一的内容,并注册该ID已经被处理过。 如果有效负载没有可用于删除重复数据的内容,则可以在消息中添加 header 并使用它。

这在您必须重置偏移量的情况下也很有用,因此服务可以 go 通过旧消息而不会中断。

我建议您在谷歌上搜索一下有关如何实现上述内容的详细信息。 这是来自 confluent 的一篇关于开发恰好一次语义的博客文章Improved Robustness and Usability of Exactly-Once Semantics in Apache Kafka解释不同语义的 Kafka 文档

关于ConsumerRebalanceListener的要点,如果您遵循在消费者中使用幂等性的解决方案,则无需执行任何操作。 当应用程序崩溃时也会发生重新平衡,在这种情况下,服务可能已经处理了一些记录,但尚未将它们提交给 Kafka。

我给所有开始使用 Kafka 的人一个小提示。 Kafka 表面上看起来很简单,但它是一项复杂的技术。 不要在生产中使用它,直到你知道它是如何工作的细节,包括已经做了一些负面测试(除非你可以接受丢失数据)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM