首页 > 解决方案 > 如何检测处于僵尸状态的 Kafka Streams 应用程序

问题描述

我们的一个 Kafka Streams 应用程序的 StreamThread 消费者在生成以下日志消息后进入了僵尸状态:

[Consumer clientId=notification-processor-db9aa8a3-6c3b-453b-b8c8-106bf2fa257d-StreamThread-1-consumer, groupId=notification-processor] 成员notification-processor-db9aa8a3-6c3b-453b-b8c8-106bf2fa257d-StreamThread-1-consumer -b2b9eac3-c374-43e2-bbc3-d9ee514a3c16 发送 LeaveGroup 请求到协调器 ****:9092 (id: 2147483646 rack: null) 由于消费者轮询超时已过期。这意味着后续调用 poll() 之间的时间比配置的 max.poll.interval.ms 长,这通常意味着轮询循环花费了太多时间来处理消息。您可以通过增加 max.poll.interval.ms 或通过使用 max.poll.records 减少 poll() 返回的批次的最大大小来解决这个问题。

StreamThread 的 Kafka Consumer 似乎已经离开了消费者组,但 Kafka Streams App 仍然处于 RUNNING 状态,而没有消费任何新记录。

我想检测到 Kafka Streams 应用程序已进入这种僵尸状态,因此可以将其关闭并替换为新实例。通常,我们通过 Kubernetes 运行状况检查来验证 Kafka Streams 应用程序是否处于 RUNNING 或 REPARTITIONING 状态,但这不适用于这种情况。

因此我有两个问题:

  1. 当 Kafka Streams 应用程序没有活跃的消费者时,是否可以预期它会保持在 RUNNING 状态?如果是:为什么?
  2. 我们如何检测(以编程方式/通过指标)Kafka Streams 应用程序已进入没有活跃消费者的僵尸状态?

标签: javaapache-kafkaapache-kafka-streamsconfluent-platform

解决方案


当 Kafka Streams 应用程序没有活跃的消费者时,是否可以预期它会保持在 RUNNING 状态?如果是:为什么?

这取决于版本。在旧版本(2.1.x 和更早版本)中,Kafka Streams 确实会保持在 RUNNING 状态,即使所有线程都死了。此问题已v2.2.0通过https://issues.apache.org/jira/browse/KAFKA-7657修复。

我们如何检测(以编程方式/通过指标)Kafka Streams 应用程序已进入没有活跃消费者的僵尸状态?

即使在旧版本中,您也可以在客户端上注册未捕获的异常处理程序KafkaStreams。每次StreamThreads死亡时都会调用此处理程序。

顺便说一句:在即将发布的 2.6.0 版本中,alive-stream-threads添加了一个新指标来跟踪正在运行的线程数:https ://issues.apache.org/jira/browse/KAFKA-9753


推荐阅读