|
1 |
| -<!-- MarkdownTOC --> |
2 |
| - |
3 |
| -- [消息队列其实很简单](#消息队列其实很简单) |
4 |
| - - [一 什么是消息队列](#一-什么是消息队列) |
5 |
| - - [二 为什么要用消息队列](#二-为什么要用消息队列) |
6 |
| - - [\(1\) 通过异步处理提高系统性能(削峰、减少响应所需时间)](#1-通过异步处理提高系统性能削峰减少响应所需时间) |
7 |
| - - [\(2\) 降低系统耦合性](#2-降低系统耦合性) |
8 |
| - - [三 使用消息队列带来的一些问题](#三-使用消息队列带来的一些问题) |
9 |
| - - [四 JMS VS AMQP](#四-jms-vs-amqp) |
10 |
| - - [4.1 JMS](#41-jms) |
11 |
| - - [4.1.1 JMS 简介](#411-jms-简介) |
12 |
| - - [4.1.2 JMS两种消息模型](#412-jms两种消息模型) |
13 |
| - - [4.1.3 JMS 五种不同的消息正文格式](#413-jms-五种不同的消息正文格式) |
14 |
| - - [4.2 AMQP](#42-amqp) |
15 |
| - - [4.3 JMS vs AMQP](#43-jms-vs-amqp) |
16 |
| - - [五 常见的消息队列对比](#五-常见的消息队列对比) |
17 |
| - |
18 |
| -<!-- /MarkdownTOC --> |
19 |
| - |
20 | 1 |
|
21 | 2 | # 消息队列其实很简单
|
22 | 3 |
|
23 | 4 | “RabbitMQ?”“Kafka?”“RocketMQ?”...在日常学习与开发过程中,我们常常听到消息队列这个关键词。我也在我的多篇文章中提到了这个概念。可能你是熟练使用消息队列的老手,又或者你是不懂消息队列的新手,不论你了不了解消息队列,本文都将带你搞懂消息队列的一些基本理论。如果你是老手,你可能从本文学到你之前不曾注意的一些关于消息队列的重要概念,如果你是新手,相信本文将是你打开消息队列大门的一板砖。
|
24 | 5 |
|
25 | 6 | ## 一 什么是消息队列
|
26 | 7 |
|
27 |
| -我们可以把消息队列比作是一个存放消息的容器,当我们需要使用消息的时候可以取出消息供自己使用。消息队列是分布式系统中重要的组件,使用消息队列主要是为了通过异步处理提高系统性能和削峰、降低系统耦合性。目前使用较多的消息队列有ActiveMQ,RabbitMQ,Kafka,RocketMQ,我们后面会一一对比这些消息队列。 |
| 8 | +**我们可以把消息队列看作是一个存放消息的容器,当我们需要使用消息的时候,直接从容器中取出消息供自己使用即可。** |
| 9 | + |
| 10 | + |
28 | 11 |
|
29 |
| -另外,我们知道队列 Queue 是一种先进先出的数据结构,所以消费消息时也是按照顺序来消费的。比如生产者发送消息1,2,3...对于消费者就会按照1,2,3...的顺序来消费。但是偶尔也会出现消息被消费的顺序不对的情况,比如某个消息消费失败又或者一个 queue 多个consumer 也会导致消息被消费的顺序不对,我们一定要保证消息被消费的顺序正确。 |
| 12 | +消息队列是分布式系统中重要的组件之一。使用消息队列主要是为了通过异步处理提高系统性能和削峰、降低系统耦合性。 |
30 | 13 |
|
31 |
| -除了上面说的消息消费顺序的问题,使用消息队列,我们还要考虑如何保证消息不被重复消费?如何保证消息的可靠性传输(如何处理消息丢失的问题)?......等等问题。所以说使用消息队列也不是十全十美的,使用它也会让系统可用性降低、复杂度提高,另外需要我们保障一致性等问题。 |
| 14 | +我们知道队列 Queue 是一种先进先出的数据结构,所以消费消息时也是按照顺序来消费的。 |
32 | 15 |
|
33 | 16 | ## 二 为什么要用消息队列
|
34 | 17 |
|
35 |
| -我觉得使用消息队列主要有两点好处: |
| 18 | +我觉得使用消息队列主要有三点好处: |
36 | 19 |
|
37 |
| -1. 通过异步处理提高系统性能(削峰、减少响应所需时间) |
38 |
| -2. 降低系统耦合性。 |
| 20 | +1. **通过异步处理提高系统性能(减少响应所需时间)。** |
| 21 | +2. **削峰/限流** |
| 22 | +3. **降低系统耦合性。** |
39 | 23 |
|
40 | 24 | 如果在面试的时候你被面试官问到这个问题的话,一般情况是你在你的简历上涉及到消息队列这方面的内容,这个时候推荐你结合你自己的项目来回答。
|
41 | 25 |
|
42 | 26 |
|
43 | 27 | 《大型网站技术架构》第四章和第七章均有提到消息队列对应用性能及扩展性的提升。
|
44 | 28 |
|
45 |
| -### (1) 通过异步处理提高系统性能(削峰、减少响应所需时间) |
| 29 | +### 2.1 通过异步处理提高系统性能(减少响应所需时间) |
| 30 | + |
| 31 | + |
46 | 32 |
|
47 | 33 | 
|
48 |
| -如上图,**在不使用消息队列服务器的时候,用户的请求数据直接写入数据库,在高并发的情况下数据库压力剧增,使得响应速度变慢。但是在使用消息队列之后,用户的请求数据发送给消息队列之后立即返回,再由消息队列的消费者进程从消息队列中获取数据,异步写入数据库。由于消息队列服务器处理速度快于数据库(消息队列也比数据库有更好的伸缩性),因此响应速度得到大幅改善。** |
49 | 34 |
|
50 |
| -通过以上分析我们可以得出**消息队列具有很好的削峰作用的功能**——即**通过异步处理,将短时间高并发产生的事务消息存储在消息队列中,从而削平高峰期的并发事务。** 举例:在电子商务一些秒杀、促销活动中,合理使用消息队列可以有效抵御促销活动刚开始大量订单涌入对系统的冲击。如下图所示: |
51 | 35 |
|
52 |
| - |
| 36 | + |
| 37 | +将用户的请求数据存储到消息队列之后就立即返回结果。随后,系统再对消息进行消费。 |
53 | 38 |
|
54 | 39 | 因为**用户请求数据写入消息队列之后就立即返回给用户了,但是请求数据在后续的业务校验、写数据库等操作中可能失败**。因此使用消息队列进行异步处理之后,需要**适当修改业务流程进行配合**,比如**用户在提交订单之后,订单数据写入消息队列,不能立即返回用户订单提交成功,需要在消息队列的订单消费者进程真正处理完该订单之后,甚至出库后,再通过电子邮件或短信通知用户订单成功**,以免交易纠纷。这就类似我们平时手机订火车票和电影票。
|
55 | 40 |
|
56 |
| -### (2) 降低系统耦合性 |
| 41 | +### 2.2 削峰/限流 |
| 42 | + |
| 43 | +**先将短时间高并发产生的事务消息存储在消息队列中,然后后端服务再慢慢根据自己的能力去消费这些消息,这样就避免直接把后端服务打垮掉。** |
| 44 | + |
| 45 | +举例:在电子商务一些秒杀、促销活动中,合理使用消息队列可以有效抵御促销活动刚开始大量订单涌入对系统的冲击。如下图所示: |
| 46 | + |
| 47 | + |
| 48 | + |
| 49 | +### 2.3 降低系统耦合性 |
57 | 50 |
|
58 | 51 | 使用消息队列还可以降低系统耦合性。我们知道如果模块之间不存在直接调用,那么新增模块或者修改模块就对其他模块影响较小,这样系统的可扩展性无疑更好一些。还是直接上图吧:
|
59 | 52 |
|
|
0 commit comments