Apache Kafka with High Level Consumer:跳过损坏的邮件

时间:2015-10-02 09:35:01

标签: apache-kafka kafka-consumer-api

我面临高级卡夫卡消费者(0.8.2.0)的问题 - 在消费了一些数据之后,我们的消费者就停止了。重新启动后,它会消耗一些消息并再次停止,没有错误/异常或警告。

经过一番调查后,我发现消费者的问题是这个例外:

ERROR c.u.u.e.impl.kafka.KafkaConsumer  - Error consuming message stream:
 kafka.message.InvalidMessageException: Message is corrupt (stored crc = 3801080313, computed crc = 2728178222)

任何想法我怎么能简单地跳过这些消息?

2 个答案:

答案 0 :(得分:2)

所以,回答我自己的问题。在对Kafka Consumer进行一些调试之后,我找到了一个可能的解决方案:

  1. 创建kafka.consumer.ConsumerIterator
  2. 的子类
  3. 覆盖makeNext - 方法。在此方法中,捕获InvalidMessageException并返回一些虚拟占位符。
  4. while - 循环中,您必须将kafka.consumer.ConsumerIterator转换为您的实施。不幸的是,kafka.consumer.ConsumerIterator的所有字段都是私有的,因此您必须使用反射。
  5. 所以这是代码示例:

    val skipIt = createKafkaSkippingIterator(ks.iterator())
    
    while(skipIt.hasNext()) {
      val messageAndTopic = skipIt.next()
    
      if (messageNotCorrupt(messageAndTopic)) {
        consumeFn(messageAndTopic)
      }
    }
    

    messageNotCorrupt - 方法只检查参数是否等于虚拟消息。

答案 1 :(得分:2)

使用Kafka 0.8.2客户端的另一种解决方案,可能更容易。

try {
  val m = it.next()
  //...
} catch {
  case e: kafka.message.InvalidMessageException ⇒
    log.warn("Corrupted message. Skipping.", e)
    resetIteratorState(it)
}

//...

def resetIteratorState(it: ConsumerIterator[Array[Byte], Array[Byte]]): Unit = {
  val method = classOf[IteratorTemplate[_]].getDeclaredMethod("resetState")
  method.setAccessible(true)
  method.invoke(it)
}