Spring-Kafka —— 消费重试机制实现

 

消息处理问题

在从Kafka主题接收消息之后立即处理消息的消费者的实现非常简单。不幸的是,现实要复杂得多,并且由于各种原因,消息处理可能会失败。其中一些原因是永久性问题,例如数据库约束失败或消息格式无效。其他,如消息处理中涉及的依赖系统的临时不可用,可以在将来解决。在这些情况下,重试消息处理可能是一种有效的解决方案。

 

 

非阻塞重试逻辑

在像Kafka这样的流媒体系统中,我们不能跳过消息并在以后回复它们。一旦我们移动当前消息中指向Kafka的指针,我们就无法返回。为简单起见,我们假设消息偏移在成功的消息处理之后就被记住了。在这种情况下,除非我们成功处理当前消息,否则我们无法接收下一条消息。如果处理单个消息不断失败,则会阻止系统处理下一条消息。很明显,我们希望避免这种情况,因为通常一次消息处理失败并不意味着下一次消息处理失败。此外,在较长时间(例如一小时)之后,由于各种原因,失败消息的处理可能成功。对他们来说,我们所依赖的系统可以再次出现。

 

在消息处理失败时,我们可以将消息的副本发布到另一个主题并等待下一条消息。让我们将新主题称为'retry_topic'。'retry_topic'的消费者将从Kafka接收消息,然后在开始消息处理之前等待一些预定义的时间,例如一小时。通过这种方式,我们可以推迟下一次消息处理尝试,而不会对'main_topic'消费者产生任何影响。如果'retry_topic'消费者中的处理失败,我们只需放弃并将消息存储在'failed_topic'中,以便进一步手动处理此问题。

 

业务重试场景

  • 'retry_timestamp',其值计算为现在+ 5分钟

总结

正如您所注意到的,在发生某些故障时实施推迟消息处理并不是一件容易的事情。请记住:

  • 您不能跳过消费并稍后再处理此消息
  • 如果要推迟处理某些消息,可以将它们重新发布到单独的主题,每个延迟值一个
  • 处理失败的消息可以通过克隆消息并将其重新发布到重试主题之一来实现,其中包含有关尝试次数和下次重试时间戳的更新信息
  • 除非是时候处理消息,否则重试主题的消费者应该阻止该线程
  • 重试主题中的消息按时间顺序自然组织,必须按顺序处理

 

问题

  

 

posted on 2019-07-13 18:07  曹伟雄  阅读(13633)  评论(2编辑  收藏  举报

导航