面试题 - Kafka、RabbitMQ、RocketMQ如何选型?

在当今的高并发、大数据时代,系统架构的复杂性呈指数级增长。你是否曾遇到过这样的问题:用户订单提交后,系统响应缓慢甚至卡顿?或者在业务高峰期,消息积压导致系统崩溃?

这些问题的背后,往往隐藏着一个核心痛点------分布式消息集群的性能瓶颈。在分布式消息队列的江湖中,Kafka、RabbitMQ和RocketMQ是三大门派的代表。Kafka以"速度"著称,RabbitMQ以"灵活"闻名,RocketMQ则以"可靠"立足。然而,在实际的分布式系统中,如何选择最适合你的消息队列?它们在性能、可靠性、扩展性以及运维成本上的差异究竟有多大?

Kafka-分布式流处理中间件

Kafka是一个基于ZooKeeper的高吞吐量、低延迟的分布式发布与消息订阅系统。它可以实时处理大量消息数据以满足各种需求。即便使用非常普通的硬件,Kafka也可以每秒处理数百万条消息,其延迟最低只有几毫秒。
利用"放鸡蛋"的例子快速了解Kafka

下面举一个生产者与消费者的例子。

生产者生产鸡蛋,消费者消费鸡蛋。假设消费者消费鸡蛋时"噎住"了(系统宕机了),而生产者还在生产鸡蛋,那么新生产的鸡蛋就丢失了;再比如,生产者1秒生产100个鸡蛋(大交易量的情况),而消费者1秒只能消费50个鸡蛋,那么过不了多长时间,消费者就"吃不消"了(消息堵塞,最终导致系统超时),导致鸡蛋又丢失了。此时,我们放1个篮子在生产者与消费者中间,生产者生产出来的鸡蛋都放到篮子里,消费者去篮子里拿鸡蛋,这样鸡蛋就不会丢失了,这个篮子就相当于Kafka。

上述例子中的鸡蛋则相当于Kafka中的消息(Message);篮子相当于存放消息的消息队列,也就是Kafka集群;当篮子满了,鸡蛋放不下时,再加几个篮子,就是Kafka集群扩容。

Kafka的消息传递流程如下图所示。生产者将消息发送给Kafka集群,同时Kafka集群将消息转发给消费者。

客户端(生产者/消费者)和Kafka集群之间的通信通过一个简单的、高性能的、与语言无关的TCP完成。Kafka不仅提供Java客户端,也提供其他多种语言的客户端。

RabbitMQ-高可用的消息队列

RabbitMQ 是一个开源的消息代理和消息队列系统,用于在分布式系统中传递消息。它是用 Erlang 语言编写的,专为高可用和多协议支持设计,非常适合在电商系统中使用。

RabbitMQ的核心组件包括生产者(Producer)、交换器(Exchange)、队列(Queue)、消费者(Consumer)和绑定(Binding)。通过这些组件,RabbitMQ能够实现消息的创建、路由、存储和处理。RabbitMQ的工作原理如下图所示。

RabbitMQ的工作流程如下

(1)生产者发送消息。生产者创建消息并将其发送到指定的交换器,同时指定一个路由键。例如,当用户下单后,下单服务(生产者)会生成一条订单消息,并将其发送到RabbitMQ的交换器。

(2)交换器路由消息。交换器收到消息后,根据路由键(例如order.created)和绑定规则决定将消息发送到哪个队列。如果匹配多个队列,则消息会被复制并发送到每个匹配的队列,例如订单处理队列和库存更新队列。

(3)队列存储消息。消息到达队列后,会被存储在队列中,等待消费者处理。如果队列没有消费者,则消息会一直保存在队列中,直到有消费者连接并处理消息。例如,订单处理队列和库存更新队列分别存储这条订单消息,等待相应的消费者进行处理。

(4)消费者处理消息。消费者连接队列,获取消息并进行处理。处理完成后,消费者会向RabbitMQ发送确认信息,表示消息已经被成功处理。RabbitMQ会将消息从消息队列中删除,确保消息不被重复处理。例如,订单处理服务(消费者)从订单处理队列中获取消息,更新订单状态并生成发货单;

库存更新服务(消费者)从库存更新队列中获取消息,减少相应商品的库存数量。

RocketMQ-低延迟高可靠

RocketMQ是一个开源的分布式消息中间件,专为高吞吐量、低延迟和高可靠性的场景设计。它支持多种消息通信模式,包括发布/订阅、点对点、延时消息和事务消息等,能够满足不同场景下的业务需求。

RocketMQ广泛应用于金融、电商、物流、大数据等领域,帮助企业构建高效、稳定的分布式系统。

RocketMQ消息通信模式1------发布/订阅模式

RocketMQ的发布/订阅模式是一种消息通信模式,使得消息的生产者(发布者)不直接发送消息给特定的消费者(订阅者),而是通过一个中间件------Broker。在这个模式下,生产者发布消息到Broker的特定主题上,而消费者则向Broker订阅感兴趣的主题。当Broker收到消息后,它负责将消息推送给订阅了该主题的所有消费者。

RocketMQ的发布/订阅模型如下图所示。

RocketMQ消息通信模式2------点对点模式

RocketMQ的点对点(Point-to-Point,P2P)模式,也称为队列模式(Queue Model),是一种简单的消息通信模式。在这种模式下,消息被发送到一个队列,每条消息只能被一个消费者接收和处理。这意味着,即使有多个消费者订阅了同一个队列,一条消息也只会被其中一个消费者消费。

RocketMQ的点对点模式如下图所示。

选择合适的消息中间件

通过比较Kafka、RabbitMQ和RocketMQ等不同消息中间件的架构设计、性能特征和适用场景,可以更好地理解如何根据具体的业务需求选择合适的消息中间件,三者的对比如表所示。

如果需要高吞吐量和实时数据处理,Kafka是一个很好的选择;如果需要传统的消息队列功能和易用性,RabbitMQ是一个不错的选择;如果需要高可用和事务消息支持,则可以考虑RocketMQ。

选择合适的消息中间件的关键策略如下

1.系统规模和扩展性

在系统规模和扩展性方面,消息中间件的选择策略如下。

小型或中型应用:如果业务规模较小,则可以考虑使用轻量级的消息中间件,如RabbitMQ或ActiveMQ。这些中间件易于安装和配置,适合初步构建和测试异步通信机制。

大型或高并发应用:对于大型或高并发的系统,如电商系统、大数据处理等,需要选择能够支持大规模部署和高吞吐量的消息中间件,如Kafka或RocketMQ。这些中间件能够处理大量消息,支持集群和负载均衡,可以确保系统的稳定性和可靠性。

2.消息传递模式

在消息传递模式方面,消息中间件的选择策略如下。

点对点(P2P):如果业务场景需要确保每个消息都只被一个消费者处理,则可以选择支持P2P模式的消息中间件,如RabbitMQ。

发布/订阅(Pub/Sub):如果业务需要广播消息到多个订阅者,则可以选择支持Pub/Sub模式的消息中间件,如Kafka或ActiveMQ。

3.延迟和吞吐量

在延迟和吞吐量方面,消息中间件的选择策略如下。

低延迟:对于需要实时或近实时处理的业务,如股票交易系统,应选择低延迟的消息中间件,如RocketMQ或Kafka。

高吞吐量:对于需要处理大量数据的业务,如日志收集和分析,应选择高吞吐量的消息中间件,如Kafka。

4.持久性和可靠性

在持久性和可靠性方面,消息中间件的选择策略如下。

持久化需求:如果业务要求消息不能丢失,则需要选择支持消息持久化的消息中间件,如Kafka或RocketMQ。

事务性消息:对于需要事务支持的业务场景,如分布式事务处理,可以选择支持事务性消息的中间件,如RabbitMQ。

5.容错性和高可用性

在容错性和高可用性方面,消息中间件的选择策略如下。

容错性:选择能够在部分节点故障时继续提供服务的消息中间件,确保业务连续性。

高可用性:对于关键业务系统,需要选择具有高可用和故障转移能力的消息中间件,如Kafka的多副本和Broker集群,或RocketMQ的NameServer和Broker集群。

相关推荐
霸道流氓气质1 天前
RabbitMQ 延迟队列与死信队列:原理、实现与实战
分布式·rabbitmq·ruby
YOU OU2 天前
RabbitMQ应用问题
分布式·rabbitmq
小园子的小菜2 天前
RocketMQ 核心原理、架构优势与核心机制全解
架构·rocketmq
YOU OU2 天前
RabbitMQ高级特性
分布式·rabbitmq
富士康质检员张全蛋2 天前
Kafka 事物
kafka
wear工程师3 天前
Kafka 消费者心跳正常,为什么还会被踢出组?拆清 max.poll.interval.ms
java·kafka
JLWcai202510093 天前
核电打磨 “安全卫士”|金利威不锈钢专用树脂砂轮,合规高效双在线
mysql·mongodb·eureka·sqlite·rabbitmq·nosql·memcached
成为你的宁宁4 天前
【Kafka KRaft 集群】
分布式·kafka
sunywz4 天前
【从零搭建物联网智能充电桩系统】选型篇:Netty、MQTT、RabbitMQ、IoTDB 为什么这么选?
物联网·rabbitmq·iotdb
2601_960906725 天前
地球或逃逸到相对安全的日心轨道
kafka·hbase·flume·storm