消息代理与事件代理:何时使用它们( 二 )


在这一部分,我将比较迄今为止最流行的两种技术:Kafka(事件代理)和RabbitMQ(消息代理),它们分别代表了这两个范式,我对它们都有实际经验 。
我强烈鼓励您在技术选择过程中考虑以下几点 。
1.轮询与推送Kafka消费者的工作方式是通过轮询一个主题中按顺序分区划分的消息的块 , 每个消费者负责从一个或多个分区中消费消息,其中分区用作消费者的并行机制(隐式线程模型) 。
这意味着通常负责管理主题的生产者会隐式知道可以订阅主题的消费者实例的最大数量 。
消费者负责处理消息处理的成功和失败情况 。由于消息是从分区中批量轮询的 , 所以消息处理顺序在分区级别是有保证的 。
RabbitMQ消费者从队列中接收消息的方式是通过代理将消息推送给它们 。
每条消息都以一种独立的方式进行处理,消费者可以采用显式线程模型 , 而不需要生产者知道消费者实例的数量 。
成功的消息处理是消费者的责任,而处理失败主要由消息代理完成 。
消息分发由代理进行管理 。
如延迟消息和消息优先级等功能是开箱即用的,因为消息处理顺序在队列中通常是不保证的 。
2.错误处理Kafka处理消息处理错误的方式是将处理错误的责任委托给消费者 。
如果某条消息被处理了几次但失败(毒药药),消费者应用程序需要跟踪处理尝试的数量,然后生成一条消息到一个单独的DLQ(死信队列)主题,以便以后检查/重新运行 。
就错误处理而言 , 消费者是承担所有责任的一方 。
这意味着如果您希望具有重试/DLQ功能,您需要提供重试机制,并在发送消息到DLQ主题时充当生产者 , 这在某些极端情况下可能导致消息丢失 。
RabbitMQ处理消息处理错误的方式是跟踪处理消息失败 。一旦一条消息被视为毒药药,它将被路由到一个DLQ交换机 。
这允许重新排队消息或将其路由到专用DLQ以进行检查 。
通过这种方式,RabbitMQ提供了保证未成功处理的消息不会丢失 。
3.消费者确认和传递保证Kafka处理消费者确认的方式是由消费者提交从主题分区中轮询的消息的偏移量 。
开箱即用 , Kafka客户端会自动提交偏移量,无论消息是否成功处理 , 这可能导致消息丢失,如下图所示 。

消息代理与事件代理:何时使用它们

文章插图
通过消费者代码负责手动提交获取的消息的偏移量 , 包括处理消息消费失败的情况,可以更改此行为 。
RabbitMQ处理消费者确认的方式是消费者以每条消息的方式进行“确认”或“否认”,允许由消息代理处理重试策略/DLQ , 如果需要,可以由消息代理进行管理 。
开箱即用,RabbitMQ客户端自动进行确认 , 无论消息是否成功处理,可以通过消费者端的配置手动控制确认,允许消息在失败/超时时重新推送给消费者 。
RabbitMQ和Kafka在大多数情况下都提供至少一次消息/事件处理的保证,这意味着消费者应该是幂等的,以处理同一消息/事件的多次处理 。
我们的流程步骤 3:根据您的用例选择技术,而不是反过来对我们来说,最重要的部分是编制我们解决方案的技术标准清单,并为我们作为团队和产品不能缺少的要求分配“不可接受” 。
回到基础精神 , 我使用了一个普通的表格来编制和比较不同的标准,并提到了一些需要注意的地方 。记住,“细节藏在细节之中” 。
消息代理与事件代理:何时使用它们

文章插图
这真的帮助我们组织并集中精力关注对我们至关重要的内容以及我们无法缺少的内容 。
例如 , 我们的“不可接受”要求之一是,如果在处理过程中发生错误,我们不能承受丢失消息 。
正如您可能从上面的部分中记得的,当使用需要DLQ的Kafka时 , 消费者也是DLQ的生产者 。这意味着在消费者发生故障的某些情况下,消息将不会被发送到DLQ主题 , 可能导致消息丢失 。
在这一点上,正如您可能已经猜到的那样,我们决定选择消息代理 。
我们的功能包括面向命令/任务的处理用例,消息代理满足了我们的产品/数据容量要求,也满足了我们团队的需求 。
最后的思考消息和事件流生态系统包括许多解决方案,每个解决方案都有许多不同的方面需要考虑和熟悉 。
重要的是我们要睁大眼睛进入每个生态系统 , 并对这些不同的范式有清晰的理解 。它们将对我们工程师的日常生活(有时是夜间生活)产生重大影响 。


推荐阅读