昆仑山

首页 » 问答 » 类别 » RabbitMQ和Kafka到底该怎么选
TUhjnbcbe - 2023/10/30 17:58:00
北京中科白癜风医院路线 https://wapyyk.39.net/hospital/89ac7_guides.html
介绍

作为一名资深程序员,我经常遇到一个不断重复的问题:“RabbitMQ和Kafka我应该使用谁?”

其实许多开发人员认为这些技术是可以互换的。虽然在某些情况下确实如此,但RabbitMQ还是Kafka之间存在根本上的差异。

因此,不同的场景需要不同的,选择错误的方案会严重影响我们的系统开发设计以及后续维护。

本系列的第1部分解释了RabbitMQ和ApacheKafka的内部实现概念。本文作为第二部分将继续回顾这两个消息平台之间的显著差异。

然后本文将继续向大家解释RabbitMQ和ApacheKafka内部实现,并评估它们之间的使用场景。

RabbitMQ和Kafka的显著区别

RabbitMQ是一个消息代理中间件,而ApacheKafka是一个分布式流处理平台。这种差异可能看起来只是语义上的,但它会带来严重的影响,影响我们方便地实现各种系统功能。

例如Kafka最适合处理流数据,在同一主题同一分区内保证消息顺序,而RabbitMQ对流中消息的顺序只提供基本的保证。

不过RabbitMQ内置了对重试逻辑和死信交换的支持,而Kafka将此类逻辑实现留给了用户。

消息顺序

RabbitMQ对发送到队列或交换器的消息的顺序性提供了很少的保证。虽然消费者按照生产者发送消息的顺序处理消息似乎很合理,但其实并不是这样。

RabbitMQ文档声明了以下有关其消息顺序的内容:

?

“在一个通道中发布的消息,经过一个交换机、一个队列和一个传出通道后,将按照发送的顺序被接收。”—RabbitMQBrokerSemantics

?

换句话说,当我们只有一个消息消费者,它就会按顺序接收消息。然而一旦我们有多个消费者从同一个队列读取消息,我们就无法保证消息的处理顺序。

发生这种缺乏排序保证的情况是因为消费者可能会在读取消息后将消息返回(或重新传递)到队列(例如在处理失败的情况下)。

一旦消息返回,另一个消费者就可以拿起它进行处理,即使它已经消费了后面的消息。因此多个消费者之间无法有序处理消息,如下图所示。

使用RabbitMQ时丢失消息排序的示例

我们可以通过将消费者并发数限制为1来重新保证RabbitMQ中的消息顺序。更准确地说,单个消费者内的线程计数要限制为1,因为任何并行的消息处理都可能导致消息乱序问题。

如果我们将自己限制为一个单线程消费者虽然能保证消息顺序,但这会严重影响我们系统扩展消息的处理能力,因此我们不应该轻易的这样做。

另一方面,Kafka为消费者在消息处理时提供了可靠的排序保证。Kafka保证发送到同一主题分区的所有消息都按顺序处理。

如果你还记得第1部分内容,默认情况下,Kafka使用循环分区程序将消息放置在分区中。但是生产者可以在每个消息上设置分区键,以创建逻辑数据流(例如来自同一设备的消息,或属于同一租户的消息)。

来自同一数据流的所有消息都会被放置在同一分区中,从而使消费者组按顺序处理它们。

我们应该注意到,在消费者组中,每个分区都是由单个消费者的单个线程处理的。因此我们无法扩展单个分区的处理。

不过在Kafka中,我们可以扩展主题内的分区数量,从而使每个分区接收更少的消息,并为额外的分区添加额外的消费者。

赢家

Kafka是明显的赢家,因为它允许消息按顺序处理。RabbitMQ在这方面只有较弱的保证。

消息路由

RabbitMQ可以根据订阅者定义的路由规则将消息路由到消息交换机的订阅者。

主题交换(topicexchange)可以基于名为routing_key的专用标头来路由消息。

标头交换(headersexchange)可以基于任意消息标头路由消息。这两种交换都有效地允许消费者指定他们有兴趣接收的消息类型,从而为架构师选择消息平台提供了极大的灵活性。

?

exchange-headers

1
查看完整版本: RabbitMQ和Kafka到底该怎么选