RabbitMQ的特点和性能
作者:程序员马丁
在线博客:https://open8gu.com
大话面试,技术同学面试必备的八股文小册,以精彩回答应对深度问题,助力你在面试中拿个offer。
回答话术
RabbitMQ 是一个开源的消息队列系统,使用 Erlang 语言编写,支持 AMQP 协议。
尽管 RabbitMQ 相对较老,但它具有持续更新、运维简单、灵活路由和客户端丰富等优点。RabbitMQ 提供了多种 Exchange 类型(Direct、Fanout、Topic 和 Headers),可以很好的满足不同的路由需求。
问题详解
1. AMQP 协议
AMQP 协议(Advanced Message Queuing Protocol,高级消息队列协议)是一种开放标准的消息传递协议,用于在不同系统之间可靠地传输消息。
主要实现包括 Apache Qpid、RabbitMQ、 等开源消息代理,但是 AMQP 的缺点也很明显,协议的复杂性、性能开销、消息大小限制、安全性不足。
2. 重要核心概念
- 连接(Connection):一个网络连接,用于与 RabbitMQ 服务端建立通信。通常连接是长连接,可以在连接上创建多个信道。
- 信道(Channel):建立在连接之上的轻量级连接。一个连接可以包含多个信道,每个信道之间是独立的、并发的通信路径。客户端可以通过信道进行消息的发送和接收。
- 交换器(Exchange):接收消息并根据路由规则将消息路由转发给绑定的队列。交换器根据消息的路由键(Routing Key)将消息发布到一个或多个队列。RabbitMQ 提供了不同类型的交换机,如直连交换机、主题交换机、扇形交换机等,用于支持不同的路由模式。
- 队列(Queue):存储消息的容器,类似于消息的缓冲区。生产者将消息发送到交换器,交换器将消息路由到相应的队列,消费者则从队列中获取消息进行处理。
- 绑定(Binding):用于建立交换器与队列之间的关联关系。绑定定义了特定的路由规则,使交换器可以将消息路由到相应的队列。
- 路由键(Routing Key):用来决定消息如何被路由到相应的队列。路由键是消息发布到交换器时附带的属性,交换器根据路由键将消息发送给绑定了匹配路由规则的队列。
通过下面这个动图可以更好的理解。
3. 性能评估
RabbitMQ 在底层消息持久化方面没有使用 MMAP、Sendfile 等零拷贝技术,这可能是其性能相对较差的一个重要原因。
另外,在架构层面上,RabbitMQ 提供了镜像队列来实现 Master 的备份。无论是生产者发送消息还是消费者拉取消息,如果请求发送到镜像队列,镜像队列需要将请求转发到 Master 进行处理,Master 处理后再将结果回复给镜像节点,最后由镜像队列回复给请求者。
运行流程如下图:
在特定硬件环境下,RabbitMQ 支持的消息吞吐量在万级到十万级之间,相比于 RocketMQ 的十万级到百万级以及 Kafka 的百万级以上吞吐量来说,RabbitMQ 的吞吐量略显不足。
4. 与 Kafka 对比
毋庸置疑,RabbitMQ 和 Kafka 是两种流行的消息队列系统。
RabbitMQ 是一个实现了 AMQP 协议的消息队列系统,注重消息可靠性和灵活性。Kafka 则是一个高吞吐量的分布式发布-订阅系统,注重高吞吐量和低延迟。
RabbitMQ 采用点对点模式,消息发送者将消息发送到队列,接收者从队列中获取。Kafka 采用发布-订阅模式,消息发送者发布到主题,所有订阅者都能接收到。
RabbitMQ 提供丰富特性和多种消息协议,适用于重要且需要确保消息投递的场景。Kafka 适用于大规模实时流数据和日志流处理。
5. 为什么 RabbitMQ 被认为很小众?
RabbitMQ 被认为比较小众主要有两个原因:
- 首先,RabbitMQ 使用 Erlang 语言编写,而 Erlang 是一种比较小众的编程语言,学习成本较高,不像 Java、Scala、C 等编程语言学起来简单。因此使用 RabbitMQ 进行扩展和二次开发的情况相对较少。
- 其次,从使用的协议来看,RabbitMQ 支持 AMQP(Advanced Message Queuing Protocol)协议,而这是其他主流消息队列不支持的。
6. 为什么又老又慢还受欢迎?
我发现从我之前的工作经历、身边一些朋友以及我面试过的候选人的简历中,好多公司在选择消息队列技术时都倾向于使用 RabbitMQ,这与它的老旧和性能差形成了鲜明的对比。
那么为什么 RabbitMQ 如此受欢迎呢?
作为一个拥有 16 年(截止 2023 年)使用历史的技术,RabbitMQ 可以称得上是一名经受考验的老兵。它的各种问题都已经被修复,有丰富的学习资料,并且性能也很稳定。
尽管 RabbitMQ 已经存在很久了,但它并没有停止更新,反而更新频繁。下图展示了近期(截止到 2023 年)发布的几个版本。
根据企业的具体需求和场景,选择适合的消息队列系统,如 RabbitMQ、RocketMQ 或 Kafka。在选择时,要考虑系统的稳定性、性能、可扩展性、运维成本等因素。
7. 运维部署方式
使用 Docker、Kubernetes 等容器技术实现可扩展服务。这种开箱即用的效果,大大降低了学习成本和运维成本。
- 安装命令:安装并配置 Docker 或其他容器平台。
- 下载命令:docker pull rabbitmq 下载 RabbitMQ 镜像。
- 运行命令:docker run -d --name rabbitmq -p 5672:5672 rabbitmq 运行 RabbitMQ 容器。