|
1 | 1 | ---
|
2 |
| -title: 消息队列基础常见面试题总结 |
| 2 | +title: 消息队列基础知识总结 |
3 | 3 | category: 高性能
|
4 | 4 | tag:
|
5 | 5 | - 消息队列
|
|
15 | 15 |
|
16 | 16 | 
|
17 | 17 |
|
18 |
| -参与消息传递的双方称为生产者和消费者,生产者负责发送消息,消费者负责处理消息。 |
| 18 | +参与消息传递的双方称为 **生产者** 和 **消费者** ,生产者负责发送消息,消费者负责处理消息。 |
19 | 19 |
|
20 | 20 | 
|
21 | 21 |
|
22 |
| -我们知道操作系统中的进程通信的一种很重要的方式就是消息队列。我们这里提到的消息队列稍微有点区别,更多指的是各个服务以及系统内部各个组件/模块之前的通信,属于一种中间件。 |
| 22 | +我们知道操作系统中的进程通信的一种很重要的方式就是消息队列。我们这里提到的消息队列稍微有点区别,更多指的是各个服务以及系统内部各个组件/模块之前的通信,属于一种 **中间件** 。 |
| 23 | + |
| 24 | +维基百科是这样介绍中间件的: |
| 25 | + |
| 26 | +> 中间件(英语:Middleware),又译中间件、中介层,是一类提供系统软件和应用软件之间连接、便于软件各部件之间的沟通的软件,应用软件可以借助中间件在不同的技术架构之间共享信息与资源。中间件位于客户机服务器的操作系统之上,管理着计算资源和网络通信。 |
| 27 | +
|
| 28 | +简单来说: **中间件就是一类为应用软件服务的软件,应用软件是为用户服务的,用户不会接触或者使用到中间件。** |
| 29 | + |
| 30 | +除了消息队列之外,常见的中间件还有 RPC 框架、分布式组件、HTTP 服务器、任务调度框架、配置中心、数据库层的分库分表工具和数据迁移工具等等。 |
| 31 | + |
| 32 | +关于中间件比较详细的介绍可以参考阿里巴巴淘系技术的一篇回答: https://www.zhihu.com/question/19730582/answer/1663627873 。 |
23 | 33 |
|
24 | 34 | 随着分布式和微服务系统的发展,消息队列在系统设计中有了更大的发挥空间,使用消息队列可以降低系统耦合性、实现任务异步、有效地进行流量削峰,是分布式和微服务系统中重要的组件之一。
|
25 | 35 |
|
26 | 36 | ## 消息队列有什么用?
|
27 | 37 |
|
28 | 38 | 通常来说,使用消息队列能为我们的系统带来下面三点好处:
|
29 | 39 |
|
30 |
| -1. **通过异步处理提高系统性能(减少响应所需时间)。** |
| 40 | +1. **通过异步处理提高系统性能(减少响应所需时间)** |
31 | 41 | 2. **削峰/限流**
|
32 | 42 | 3. **降低系统耦合性。**
|
33 | 43 |
|
|
63 | 73 |
|
64 | 74 | 另外,为了避免消息队列服务器宕机造成消息丢失,会将成功发送到消息队列的消息存储在消息生产者服务器上,等消息真正被消费者服务器处理后才删除消息。在消息队列服务器宕机后,生产者服务器会选择分布式消息队列服务器集群中的其他服务器发布消息。
|
65 | 75 |
|
66 |
| -**备注:** 不要认为消息队列只能利用发布-订阅模式工作,只不过在解耦这个特定业务环境下是使用发布-订阅模式的。除了发布-订阅模式,还有点对点订阅模式(一个消息只有一个消费者),我们比较常用的是发布-订阅模式。另外,这两种消息模型是 JMS 提供的,AMQP 协议还提供了 5 种消息模型。 |
| 76 | +**备注:** 不要认为消息队列只能利用发布-订阅模式工作,只不过在解耦这个特定业务环境下是使用发布-订阅模式的。除了发布-订阅模式,还有点对点订阅模式(一个消息只有一个消费者),我们比较常用的是发布-订阅模式。另外,这两种消息模型是 JMS 提供的,AMQP 协议还提供了另外 5 种消息模型。 |
| 77 | + |
| 78 | +### 实现分布式事务 |
| 79 | + |
| 80 | +我们知道分布式事务的解决方案之一就是 MQ 事务。 |
67 | 81 |
|
68 |
| -## 使用消息队列哪些问题? |
| 82 | +RocketMQ 、 Kafka、Pulsar 、QMQ 都提供了事务相关的功能。事务允许事件流应用将消费,处理,生产消息整个过程定义为一个原子操作。 |
| 83 | + |
| 84 | +详细介绍可以查看 [分布式事务详解(付费)](https://javaguide.cn/distributed-system/distributed-transaction.html) 这篇文章。 |
| 85 | + |
| 86 | + |
| 87 | + |
| 88 | +## 使用消息队列会带来哪些问题? |
69 | 89 |
|
70 | 90 | - **系统可用性降低:** 系统可用性在某种程度上降低,为什么这样说呢?在加入 MQ 之前,你不用考虑消息丢失或者说 MQ 挂掉等等的情况,但是,引入 MQ 之后你就需要去考虑了!
|
71 | 91 | - **系统复杂性提高:** 加入 MQ 之后,你需要保证消息没有被重复消费、处理消息丢失的情况、保证消息传递的顺序性等等问题!
|
|
75 | 95 |
|
76 | 96 | ### JMS 是什么?
|
77 | 97 |
|
78 |
| -JMS(JAVA Message Service,java 消息服务)是 java 的消息服务,JMS 的客户端之间可以通过 JMS 服务进行异步的消息传输。**JMS(JAVA Message Service,Java 消息服务)API 是一个消息服务的标准或者说是规范**,允许应用程序组件基于 JavaEE 平台创建、发送、接收和读取消息。它使分布式通信耦合度更低,消息服务更加可靠以及异步性。 |
| 98 | +JMS(JAVA Message Service,java 消息服务)是 Java 的消息服务,JMS 的客户端之间可以通过 JMS 服务进行异步的消息传输。**JMS(JAVA Message Service,Java 消息服务)API 是一个消息服务的标准或者说是规范**,允许应用程序组件基于 JavaEE 平台创建、发送、接收和读取消息。它使分布式通信耦合度更低,消息服务更加可靠以及异步性。 |
79 | 99 |
|
80 | 100 | JMS 定义了五种不同的消息正文格式以及调用的消息类型,允许你发送并接收以一些不同形式的数据:
|
81 | 101 |
|
82 |
| -- StreamMessage:Java 原始值的数据流 |
83 |
| -- MapMessage:一套名称-值对 |
84 |
| -- TextMessage:一个字符串对象 |
85 |
| -- ObjectMessage:一个序列化的 Java 对象 |
86 |
| -- BytesMessage:一个字节的数据流 |
| 102 | +- `StreamMessage:Java` 原始值的数据流 |
| 103 | +- `MapMessage`:一套名称-值对 |
| 104 | +- `TextMessage`:一个字符串对象 |
| 105 | +- `ObjectMessage`:一个序列化的 Java 对象 |
| 106 | +- `BytesMessage`:一个字节的数据流 |
87 | 107 |
|
88 | 108 | **ActiveMQ(已被淘汰) 就是基于 JMS 规范实现的。**
|
89 | 109 |
|
@@ -120,9 +140,20 @@ AMQP,即 Advanced Message Queuing Protocol,一个提供统一消息服务的
|
120 | 140 | **总结:**
|
121 | 141 |
|
122 | 142 | - AMQP 为消息定义了线路层(wire-level protocol)的协议,而 JMS 所定义的是 API 规范。在 Java 体系中,多个 client 均可以通过 JMS 进行交互,不需要应用修改代码,但是其对跨平台的支持较差。而 AMQP 天然具有跨平台、跨语言特性。
|
123 |
| -- JMS 支持 TextMessage、MapMessage 等复杂的消息类型;而 AMQP 仅支持 byte[] 消息类型(复杂的类型可序列化后发送)。 |
| 143 | +- JMS 支持 `TextMessage`、`MapMessage` 等复杂的消息类型;而 AMQP 仅支持 `byte[]` 消息类型(复杂的类型可序列化后发送)。 |
124 | 144 | - 由于 Exchange 提供的路由算法,AMQP 可以提供多样化的路由方式来传递消息到消息队列,而 JMS 仅支持 队列 和 主题/订阅 方式两种。
|
125 | 145 |
|
| 146 | +## RPC 和消息队列的区别 |
| 147 | + |
| 148 | +RPC 和消息队列都是分布式微服务系统中重要的组件之一,下面我们来简单对比一下两者: |
| 149 | + |
| 150 | +- **从用途来看** :RPC 主要用来解决两个服务的远程通信问题,不需要了解底层网络的通信机制。通过 RPC 可以帮助我们调用远程计算机上某个服务的方法,这个过程就像调用本地方法一样简单。消息队列主要用来降低系统耦合性、实现任务异步、有效地进行流量削峰。 |
| 151 | +- **从通信方式来看** :RPC 是双向直接网络通讯,消息队列是单向引入中间载体的网络通讯。 |
| 152 | +- **从架构上来看** :消息队列需要把消息存储起来,RPC 则没有这个要求,因为前面也说了 RPC 是双向直接网络通讯。 |
| 153 | +- **从请求处理的时效性来看** :通过 RPC 发出的调用一般会立即被处理,存放在消息队列中的消息并不一定会立即被处理。 |
| 154 | + |
| 155 | +RPC 和消息队列本质上是网络通讯的两种不同的实现机制,两者的用途不同,万不可将两者混为一谈。 |
| 156 | + |
126 | 157 | ## 消息队列技术选型
|
127 | 158 |
|
128 | 159 | ### 常见的消息队列有哪些?
|
@@ -242,8 +273,10 @@ Pulsar 更新记录(可以直观看到项目是否还在维护):https://gi
|
242 | 273 | - RabbitMQ 在吞吐量方面虽然稍逊于 Kafka 、RocketMQ 和 Pulsar,但是由于它基于 Erlang 开发,所以并发能力很强,性能极其好,延时很低,达到微秒级。但是也因为 RabbitMQ 基于 Erlang 开发,所以国内很少有公司有实力做 Erlang 源码级别的研究和定制。如果业务场景对并发量要求不是太高(十万级、百万级),那这几种消息队列中,RabbitMQ 或许是你的首选。
|
243 | 274 | - RocketMQ 和 Pulsar 支持强一致性,对消息一致性要求比较高的场景可以使用。
|
244 | 275 | - RocketMQ 阿里出品,Java 系开源项目,源代码我们可以直接阅读,然后可以定制自己公司的 MQ,并且 RocketMQ 有阿里巴巴的实际业务场景的实战考验。
|
245 |
| -- Kafka 的特点其实很明显,就是仅仅提供较少的核心功能,但是提供超高的吞吐量,ms 级的延迟,极高的可用性以及可靠性,而且分布式可以任意扩展。同时 kafka 最好是支撑较少的 topic 数量即可,保证其超高吞吐量。Kafka 唯一的一点劣势是有可能消息重复消费,那么对数据准确性会造成极其轻微的影响,在大数据领域中以及日志采集中,这点轻微影响可以忽略这个特性天然适合大数据实时计算以及日志收集。如果是大数据领域的实时计算、日志采集等场景,用 Kafka 是业内标准的,绝对没问题,社区活跃度很高,绝对不会黄,何况几乎是全世界这个领域的事实性规范。 |
| 276 | +- Kafka 的特点其实很明显,就是仅仅提供较少的核心功能,但是提供超高的吞吐量,ms 级的延迟,极高的可用性以及可靠性,而且分布式可以任意扩展。同时 Kafka 最好是支撑较少的 topic 数量即可,保证其超高吞吐量。Kafka 唯一的一点劣势是有可能消息重复消费,那么对数据准确性会造成极其轻微的影响,在大数据领域中以及日志采集中,这点轻微影响可以忽略这个特性天然适合大数据实时计算以及日志收集。如果是大数据领域的实时计算、日志采集等场景,用 Kafka 是业内标准的,绝对没问题,社区活跃度很高,绝对不会黄,何况几乎是全世界这个领域的事实性规范。 |
246 | 277 |
|
247 | 278 | ## 参考
|
248 | 279 |
|
| 280 | +- 《大型网站技术架构 》 |
249 | 281 | - KRaft: Apache Kafka Without ZooKeeper:https://developer.confluent.io/learn/kraft/
|
| 282 | +- 消息队列的使用场景是什么样的?:https://mp.weixin.qq.com/s/4V1jI6RylJr7Jr9JsQe73A |
0 commit comments