基础知识
约 2229 字大约 7 分钟
2025-01-25
1.消息队列定义
消息队列是一种先进先出(FIFO)的数据结构,用于在应用程序之间传递消息。它提供了一种解耦、异步和可靠的消息传递机制,使得应用程序可以独立地运行,并通过消息队列进行通信。
参与消息传递的双方称为 生产者 和 消费者 ,生产者负责发送消息,消费者负责处理消息。

2.消息队列作用
- 通过异步处理提高系统性能,减少响应所需时间
- 削峰,限流(先将短时间高并发产生的事务消息存储在消息队列中,然后后端服务再慢慢根据自己的能力去消费这些消息)
- 降低系统耦合性,我们知道如果模块之间不存在直接调用,那么新增模块或者修改模块就对其他模块影响较小,这样系统的可扩展性无疑更好一些。还是直接上图吧:
消息队列使用发布-订阅模式工作,消息发送者(生产者)发布消息,一个或多个消息接受者(消费者)订阅消息。 从上图可以看到消息发送者(生产者)和消息接受者(消费者)之间没有直接耦合,消息发送者将消息发送至分布式消息队列即结束对消息的处理,消息接受者从分布式消息队列获取该消息后进行后续处理,并不需要知道该消息从何而来。对新增业务,只要对该类消息感兴趣,即可订阅该消息,对原有系统和业务没有任何影响,从而实现网站业务的可扩展性设计。
3.消息队列缺点
- 系统可用性降低: 系统可用性在某种程度上降低,为什么这样说呢?在加入 MQ 之前,你不用考虑消息丢失或者说 MQ 挂掉等等的情况,但是,引入 MQ 之后你就需要去考虑了!
- 系统复杂性提高: 加入 MQ 之后,你需要保证消息没有被重复消费、处理消息丢失的情况、保证消息传递的顺序性等等问题!
- 一致性问题: 我上面讲了消息队列可以实现异步,消息队列带来的异步确实可以提高系统响应速度。但是,万一消息的真正消费者并没有正确消费消息怎么办?这样就会导致数据不一致的情况了
4.JMS和AMQP
JMS(java message service):java消息服务
支持java平台,不跨语言,本质就是javaAPI,相当于就是一个规范。提供大量的message结构
AMQP(advanced message queuing protocol):高级消息队列协议
- 跨语言跨平台,是一个网络线级协议。只提供byte数组传输。
- RabbitMQ是AMQP的实现
对比如下:

4.JMS的两种消息模型
4.1 点对点(P2P)模型
使用**队列(Queue)*作为消息通信载体;满足*生产者与消费者模式,一条消息只能被一个消费者使用,未被消费的消息在队列中保留直到被消费或超时。比如:我们生产者发送 100 条消息的话,两个消费者来消费一般情况下两个消费者会按照消息发送的顺序各自消费一半(也就是你一个我一个的消费。)
4.2 发布/订阅(Pub/Sub)模型
作为消息通信载体,类似于广播模式;
发布者发布一条消息,该消息通过主题传递给所有的订阅者
5.消息队列技术选型
5.1 Kafka
Kafka 是 LinkedIn 开源的一个分布式流式处理平台,已经成为 Apache 顶级项目,早期被用来用于处理海量的日志,后面才慢慢发展成了一款功能全面的高性能消息队列。
- 消息队列:发布和订阅消息流,这个功能类似于消息队列,这也是 Kafka 也被归类为消息队列的原因。
- 容错的持久方式存储记录消息流:Kafka 会把消息持久化到磁盘,有效避免了消息丢失的风险。
- 流式处理平台: 在消息发布的时候进行处理,Kafka 提供了一个完整的流式处理类库。
Kafka 是一个分布式系统,由通过高性能 TCP 网络协议进行通信的服务器和客户端组成,可以部署在在本地和云环境中的裸机硬件、虚拟机和容器上。
5.2 RocketMQ
RocketMQ 是阿里开源的一款云原生“消息、事件、流”实时数据处理平台,借鉴了 Kafka,已经成为 Apache 顶级项目。
- 云原生:生与云,长与云,无限弹性扩缩,K8s 友好
- 高吞吐:万亿级吞吐保证,同时满足微服务与大数据场景。
- 流处理:提供轻量、高扩展、高性能和丰富功能的流计算引擎。
- 金融级:金融级的稳定性,广泛用于交易核心链路。
- 架构极简:零外部依赖,Shared-nothing 架构。
- 生态友好:无缝对接微服务、实时计算、数据湖等周边生态。
5.3 RabbitMQ
RabbitMQ 是采用 Erlang 语言实现 AMQP(Advanced Message Queuing Protocol,高级消息队列协议)的消息中间件,它最初起源于金融系统,用于在分布式系统中存储转发消息。
- 可靠性: RabbitMQ 使用一些机制来保证消息的可靠性,如持久化、传输确认及发布确认等。
- 灵活的路由: 在消息进入队列之前,通过交换器来路由消息。对于典型的路由功能,RabbitMQ 己经提供了一些内置的交换器来实现。针对更复杂的路由功能,可以将多个交换器绑定在一起,也可以通过插件机制来实现自己的交换器。这个后面会在我们讲 RabbitMQ 核心概念的时候详细介绍到。
- 扩展性: 多个 RabbitMQ 节点可以组成一个集群,也可以根据实际业务情况动态地扩展集群中节点。
- 高可用性: 队列可以在集群中的机器上设置镜像,使得在部分节点出现问题的情况下队列仍然可用。
- 支持多种协议: RabbitMQ 除了原生支持 AMQP 协议,还支持 STOMP、MQTT 等多种消息中间件协议。
- 多语言客户端: RabbitMQ 几乎支持所有常用语言,比如 Java、Python、Ruby、PHP、C#、JavaScript 等。
- 易用的管理界面: RabbitMQ 提供了一个易用的用户界面,使得用户可以监控和管理消息、集群中的节点等。在安装 RabbitMQ 的时候会介绍到,安装好 RabbitMQ 就自带管理界面。
- 插件机制: RabbitMQ 提供了许多插件,以实现从多方面进行扩展,当然也可以编写自己的插件。感觉这个有点类似 Dubbo 的 SPI 机
5.4 技术选型
特性 | Kafka | RocketMQ | RabbitMQ | ActiveMQ |
---|---|---|---|---|
单机吞吐量 | 10万级 | 10万级 | 万级 | 10万级 |
开发语言 | Scala | Java | Erlang | Java |
高可用 | 分布式 | 分布式 | 主从 | 分布式 |
消息延迟 | ms级 | ms级 | us级 | ms级 |
消息丢失 | 理论上不会丢失 | 理论上不会丢失 | 低 | 低 |
消费模式 | 拉取 | 推拉 | 推拉 | |
持久化 | 文件 | 内存,文件 | 内存,文件,数据库 | |
支持协议 | 自定义协议 | 自定义协议 | AMQP,XMPP, SMTP,STOMP | AMQP,MQTT,OpenWire,STOMP |
社区活跃度 | 高 | 中 | 高 | 高 |
管理界面 | web console | 好 | 一般 | |
部署难度 | 中 | 低 | ||
部署方式 | 独立 | 独立 | 独立 | 独立,嵌入 |
成熟度 | 成熟 | 比较成熟 | 成熟 | 成熟 |
优点 | 拥有强大的性能及吞吐量,兼容性很好 | 性能好,稳定可靠,有活跃的中文社区,特点响应快 | 产品成熟,容易部署和使用,拥有灵活的路由配置 | 产品成熟,支持协议多,支持多种语言的客户端 |
缺点 | 由于支持消息堆积,导致延迟比较高 | 兼容性较差,但随着影响力的扩大,该问题会有改善。 | 性能和吞吐量较差,不易进行二次开发。 | 社区不活跃,存在消息丢失的可能。 |
总结起来,电商、金融等对事务性要求很高的,可以考虑RocketMQ;技术挑战不是特别高,用 RabbitMQ 是不错的选择;如果是大数据领域的实时计算、日志采集等场景可以考虑 Kafka。