1
0
mirror of https://github.com/Snailclimb/JavaGuide synced 2025-06-25 02:27:10 +08:00

[refractor]消息队列md样式

This commit is contained in:
guide 2021-03-29 11:18:26 +08:00
parent dcbdf7b9fb
commit 5b6ad060cf
2 changed files with 39 additions and 54 deletions

View File

@ -266,11 +266,11 @@ Dubbo 是一款国产的 RPC 框架,由阿里开源。相关阅读:
#### 消息队列
消息队列在分布式系统中主要是为了解耦和削峰。相关阅读: **[消息队列总结](docs/system-design/distributed-system/message-queue/message-queue.md)**
消息队列在分布式系统中主要是为了解耦和削峰。相关阅读: [消息队列常见问题总结](docs/system-design/distributed-system/message-queue/message-queue.md)。
1. **RabbitMQ** : [RabbitMQ 入门](docs/system-design/distributed-system/message-queue/RabbitMQ入门看这一篇就够了.md)
2. **RocketMQ** : [RocketMQ 入门](docs/system-design/distributed-system/message-queue/RocketMQ.md)、[RocketMQ 的几个简单问题与答案](docs/system-design/distributed-system/message-queue/RocketMQ-Questions.md)
3. **Kafka** [Kafka 常见面试题总结](docs/system-design/distributed-system/message-queue/Kafka常见面试题总结.md)
3. **Kafka** [Kafka 常见题总结](docs/system-design/distributed-system/message-queue/Kafka常见面试题总结.md)
#### 读写分离

View File

@ -1,11 +1,10 @@
# 消息队列其实很简单
“RabbitMQ”“Kafka”“RocketMQ”...在日常学习与开发过程中,我们常常听到消息队列这个关键词。我也在我的多篇文章中提到了这个概念。可能你是熟练使用消息队列的老手,又或者你是不懂消息队列的新手,不论你了不了解消息队列,本文都将带你搞懂消息队列的一些基本理论。如果你是老手,你可能从本文学到你之前不曾注意的一些关于消息队列的重要概念,如果你是新手,相信本文将是你打开消息队列大门的一板砖。
## 一 什么是消息队列
**我们可以把消息队列看作是一个存放消息的容器,当我们需要使用消息的时候,直接从容器中取出消息供自己使用即可。**
我们可以把消息队列看作是一个存放消息的容器,当我们需要使用消息的时候,直接从容器中取出消息供自己使用即可。
![Message queue](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97/message-queue-small.png)
@ -15,7 +14,7 @@
## 二 为什么要用消息队列
我觉得使用消息队列主要有三点好处:
通常来说,使用消息队列能为我们的系统带来下面三点好处:
1. **通过异步处理提高系统性能(减少响应所需时间)。**
2. **削峰/限流**
@ -23,20 +22,15 @@
如果在面试的时候你被面试官问到这个问题的话,一般情况是你在你的简历上涉及到消息队列这方面的内容,这个时候推荐你结合你自己的项目来回答。
《大型网站技术架构》第四章和第七章均有提到消息队列对应用性能及扩展性的提升。
### 2.1 通过异步处理提高系统性能(减少响应所需时间)
![通过异步处理提高系统性能](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/Asynchronous-message-queue.png)
将用户的请求数据存储到消息队列之后就立即返回结果。随后,系统再对消息进行消费。
因为**用户请求数据写入消息队列之后就立即返回给用户了,但是请求数据在后续的业务校验、写数据库等操作中可能失败**。因此使用消息队列进行异步处理之后,需要**适当修改业务流程进行配合**,比如**用户在提交订单之后,订单数据写入消息队列,不能立即返回用户订单提交成功,需要在消息队列的订单消费者进程真正处理完该订单之后,甚至出库后,再通过电子邮件或短信通知用户订单成功**,以免交易纠纷。这就类似我们平时手机订火车票和电影票。
因为用户请求数据写入消息队列之后就立即返回给用户了,但是请求数据在后续的业务校验、写数据库等操作中可能失败。因此**使用消息队列进行异步处理之后,需要适当修改业务流程进行配合**,比如用户在提交订单之后,订单数据写入消息队列,不能立即返回用户订单提交成功,需要在消息队列的订单消费者进程真正处理完该订单之后,甚至出库后,再通过电子邮件或短信通知用户订单成功,以免交易纠纷。这就类似我们平时手机订火车票和电影票。
### 2.2 削峰/限流
@ -58,9 +52,9 @@
消息接受者对消息进行过滤、处理、包装后,构造成一个新的消息类型,将消息继续发送出去,等待其他消息接受者订阅该消息。因此基于事件(消息对象)驱动的业务架构可以是一系列流程。
**另外为了避免消息队列服务器宕机造成消息丢失,会将成功发送到消息队列的消息存储在消息生产者服务器上,等消息真正被消费者服务器处理后才删除消息。在消息队列服务器宕机后,生产者服务器会选择分布式消息队列服务器集群中的其他服务器发布消息。**
另外为了避免消息队列服务器宕机造成消息丢失,会将成功发送到消息队列的消息存储在消息生产者服务器上,等消息真正被消费者服务器处理后才删除消息。在消息队列服务器宕机后,生产者服务器会选择分布式消息队列服务器集群中的其他服务器发布消息。
**备注:** 不要认为消息队列只能利用发布-订阅模式工作,只不过在解耦这个特定业务环境下是使用发布-订阅模式的。**除了发布-订阅模式,还有点对点订阅模式(一个消息只有一个消费者),我们比较常用的是发布-订阅模式。** 另外,这两种消息模型是 JMS 提供的AMQP 协议还提供了 5 种消息模型。
**备注:** 不要认为消息队列只能利用发布-订阅模式工作,只不过在解耦这个特定业务环境下是使用发布-订阅模式的。除了发布-订阅模式,还有点对点订阅模式(一个消息只有一个消费者),我们比较常用的是发布-订阅模式。另外,这两种消息模型是 JMS 提供的AMQP 协议还提供了 5 种消息模型。
## 三 使用消息队列带来的一些问题
@ -80,17 +74,15 @@ JMSJAVA Message Service,java消息服务是java的消息服务JMS的客
#### 4.1.2 JMS 两种消息模型
①点到点P2P模型
** 点到点P2P模型**
![点到点P2P模型](https://user-gold-cdn.xitu.io/2018/4/21/162e7185572ca37d?w=575&h=135&f=gif&s=8530)
  
使用**队列Queue**作为消息通信载体;满足**生产者与消费者模式**,一条消息只能被一个消费者使用,未被消费的消息在队列中保留直到被消费或超时。比如:我们生产者发送 100 条消息的话,两个消费者来消费一般情况下两个消费者会按照消息发送的顺序各自消费一半(也就是你一个我一个的消费。)
② 发布/订阅Pub/Sub模型
**② 发布/订阅Pub/Sub模型**
![发布/订阅Pub/Sub模型](https://user-gold-cdn.xitu.io/2018/4/21/162e7187c268eaa5?w=402&h=164&f=gif&s=15492)
  
发布订阅模型Pub/Sub 使用**主题Topic**作为消息通信载体,类似于**广播模式**;发布者发布一条消息,该消息通过主题传递给所有的订阅者,**在一条消息广播之后才订阅的用户则是收不到该条消息的**。
@ -104,7 +96,6 @@ JMS定义了五种不同的消息正文格式以及调用的消息类型
- ObjectMessage--一个序列化的 Java 对象
- BytesMessage--一个字节的数据流
### 4.2 AMQP
AMQP即 Advanced Message Queuing Protocol一个提供统一消息服务的应用层标准 **高级消息队列协议**(二进制应用层协议),是应用层协议的一个开放标准,为面向消息的中间件设计,兼容 JMS。基于此协议的客户端与消息中间件可传递消息并不受客户端/中间件同产品,不同的开发语言等条件的限制。
@ -113,9 +104,8 @@ AMQP即Advanced Message Queuing Protocol一个提供统一消息服务的
### 4.3 JMS vs AMQP
| 对比方向 | JMS | AMQP |
| :-------- | --------:| :--: |
| :----------- | --------------------------------------: | :----------------------------------------------------------: |
| 定义 | Java API | 协议 |
| 跨语言 | 否 | 是 |
| 跨平台 | 否 | 是 |
@ -128,19 +118,15 @@ AMQP即Advanced Message Queuing Protocol一个提供统一消息服务的
- JMS 支持 TextMessage、MapMessage 等复杂的消息类型;而 AMQP 仅支持 byte[] 消息类型(复杂的类型可序列化后发送)。
- 由于 Exchange 提供的路由算法AMQP 可以提供多样化的路由方式来传递消息到消息队列,而 JMS 仅支持 队列 和 主题/订阅 方式两种。
## 五 常见的消息队列对比
对比方向 |概要
-------- | ---
吞吐量| 万级的 ActiveMQ 和 RabbitMQ 的吞吐量ActiveMQ 的性能最差)要比 十万级甚至是百万级的 RocketMQ 和 Kafka 低一个数量级。
可用性| 都可以实现高可用。ActiveMQ 和 RabbitMQ 都是基于主从架构实现高可用性。RocketMQ 基于分布式架构。 kafka 也是分布式的,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用
时效性| RabbitMQ 基于erlang开发所以并发能力很强性能极其好延时很低达到微秒级。其他三个都是 ms 级。
功能支持| 除了 Kafka其他三个功能都较为完备。 Kafka 功能较为简单主要支持简单的MQ功能在大数据领域的实时计算以及日志采集被大规模使用是事实上的标准
消息丢失| ActiveMQ 和 RabbitMQ 丢失的可能性非常低, RocketMQ 和 Kafka 理论上不会丢失。
| 对比方向 | 概要 |
| -------- | ------------------------------------------------------------ |
| 吞吐量 | 万级的 ActiveMQ 和 RabbitMQ 的吞吐量ActiveMQ 的性能最差)要比 十万级甚至是百万级的 RocketMQ 和 Kafka 低一个数量级。 |
| 可用性 | 都可以实现高可用。ActiveMQ 和 RabbitMQ 都是基于主从架构实现高可用性。RocketMQ 基于分布式架构。 kafka 也是分布式的,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用 |
| 时效性 | RabbitMQ 基于 erlang 开发,所以并发能力很强,性能极其好,延时很低,达到微秒级。其他三个都是 ms 级。 |
| 功能支持 | 除了 Kafka其他三个功能都较为完备。 Kafka 功能较为简单,主要支持简单的 MQ 功能,在大数据领域的实时计算以及日志采集被大规模使用,是事实上的标准 |
| 消息丢失 | ActiveMQ 和 RabbitMQ 丢失的可能性非常低, RocketMQ 和 Kafka 理论上不会丢失。 |
**总结:**
@ -149,5 +135,4 @@ AMQP即Advanced Message Queuing Protocol一个提供统一消息服务的
- RocketMQ 阿里出品Java 系开源项目,源代码我们可以直接阅读,然后可以定制自己公司的 MQ并且 RocketMQ 有阿里巴巴的实际业务场景的实战考验。RocketMQ 社区活跃度相对较为一般,不过也还可以,文档相对来说简单一些,然后接口这块不是按照标准 JMS 规范走的有些系统要迁移需要修改大量代码。还有就是阿里出台的技术,你得做好这个技术万一被抛弃,社区黄掉的风险,那如果你们公司有技术实力我觉得用 RocketMQ 挺好的
- Kafka 的特点其实很明显就是仅仅提供较少的核心功能但是提供超高的吞吐量ms 级的延迟,极高的可用性以及可靠性,而且分布式可以任意扩展。同时 kafka 最好是支撑较少的 topic 数量即可保证其超高吞吐量。kafka 唯一的一点劣势是有可能消息重复消费,那么对数据准确性会造成极其轻微的影响,在大数据领域中以及日志采集中,这点轻微影响可以忽略这个特性天然适合大数据实时计算以及日志收集。
参考《Java 工程师面试突击第 1 季-中华石杉老师》