通过 Apache Kafka 中的死信队列进行错误处理

Apache Kafka 中用于错误处理的死信队列:来自 Uber 和 Crowdstrike 的替代方案、最佳实践和案例研究 。
识别和处理错误对于任何可靠的数据流管道都是必不可少的 。这篇博文探讨了 在 Apache Kafka 基础架构中使用死信队列实现错误处理的最佳实践 。这些选项包括自定义实现、Kafka Streams、Kafka Connect、Spring 框架和并行消费者 。真实案例研究展示了 Uber、CrowdStrike 和桑坦德银行如何以极端规模构建可靠的实时错误处理 。
Apache Kafka 成为许多企业架构最喜欢的集成中间件 。即使对于云优先战略,企业也可以利用 Kafka 的数据流作为云原生集成平台即服务 (iPaaS) 。
Apache Kafka 数据流中的消息队列模式
在我开始这篇文章之前,我想让你知道这个内容是关于“JMS、消息队列和 Apache Kafka”的博客系列的一部分:
 

  1. JMS 消息代理与 Apache Kafka 数据流的10 个比较标准
  2. 这篇文章– 通过Apache Kafka 中的死信队列 (DQL)进行错误处理的替代方法
  3. 使用 Apache Kafka实现请求-回复模式
  4. 即将推出——用于选择正确消息系统的决策树(JMS 与 Apache Kafka)
  5. 即将推出——从 JMS 消息代理到 Apache Kafka:集成、迁移和/或替换
什么是死信队列集成模式(在 Apache Kafka 中)? 
死信队列 (DLQ)是消息系统或数据流平台内的一种服务实现,用于存储未成功处理的消息 。系统不是被动地转储消息,而是将其移动到死信队列 。
企业集成模式 (EIP)改为调用设计模式死信通道 。我们可以将两者用作同义词 。
通过 Apache Kafka 中的死信队列进行错误处理

文章插图
本文重点介绍数据流平台 Apache Kafka 。在 Kafka 中将消息放入 DLQ 的主要原因通常是消息格式错误或消息内容无效/缺失 。例如,如果预期值是整数,但生产者发送了字符串,则会发生应用程序错误 。在更动态的环境中,“主题不存在”异常可能是无法传递消息的另一个错误 。
因此,通常不要使用现有中间件经验中的知识 。Message Queue 中间件(如符合 JMS 的 IBM MQ、TIBCO EMS 或 RabbitMQ)与分布式提交日志(如 Kafka)的工作方式不同 。由于许多其他原因,消息队列中的 DLQ 用于消息队列系统,这些原因不能一对一地映射到 Kafka 。例如,MQ 系统中的消息由于每条消息的 TTL(生存时间)而过期 。
因此,在 Kafka 中将消息放入 DLQ 的主要原因是消息格式错误或消息内容无效/缺失 。
Apache Kafka 中死信队列的替代方案
Kafka 中的死信队列是一个或多个 Kafka 主题,它们接收和存储由于错误而无法在另一个流管道中处理的消息 。此概念允许使用以下传入消息继续消息流,而不会由于无效消息的错误而停止工作流 。
Kafka Broker 很笨——智能端点提供错误处理
Kafka 架构不支持 broker r 中的DLQ 。有意地,Kafka 建立在与现代微服务相同的原则上,使用“哑管道和智能端点”原则 。这就是为什么与传统消息代理相比,Kafka 的扩展性如此之好 。过滤和错误处理发生在客户端应用程序中 。
数据流平台的真正解耦可以实现更干净的领域驱动设计 。每个微服务或应用程序都通过自己选择的技术、通信范式和错误处理来实现其逻辑 。
在传统的中间件和消息队列中,代理提供了这种逻辑 。结果是域中的可扩展性和灵活性较差,因为只有中间件团队才能实现集成逻辑 。
用任何编程语言自定义实现 Kafka 死信队列
Kafka 中的死信队列独立于您使用的框架 。一些组件为错误处理和死信队列提供了开箱即用的功能 。但是,使用JAVA、Go、C++、Python/ target=_blank class=infotextkey>Python 等任何编程语言为 Kafka 应用程序编写死信队列逻辑也很容易 。
死信队列实现的源代码包含一个 try-catch 块来处理预期或意外异常 。如果没有发生错误,则处理该消息 。如果发生任何异常,请将消息发送到专用的 DLQ Kafka 主题 。
失败原因应添加到 Kafka 消息的标头中 。不应更改键和值,以便将来对历史事件进行重新处理和故障分析 。
死信队列的开箱即用 Kafka 实现
你并不总是需要实现你的死信队列 。许多组件和框架已经提供了它们的 DLQ 实现 。
使用您自己的应用程序,您通常可以控制错误或在出现错误时修复代码 。但是,与 3rd 方应用程序的集成并不一定允许您处理可能跨集成障碍引入的错误 。因此,DLQ 变得更加重要,并被包含在某些框架中 。


推荐阅读