消息队列(一)——消息队列的应用场景

以下是本消息队列系列文章的传送门:

1. 什么是消息队列


队列相信大家应该都不陌生,它是一种先进先出的数据结构,基本结构如下图。

队列

在java中已经实现了各种各样的队列了,那为什么还需要消息队列MQ(Message Queue)这种中间件呢?我们可以先尝试思考一下消息队列存在的意义,它能满足我们项目中的什么需求,下面我会继续补充。

消息队列可以简单理解为,我们把想要传输的数据放到队列中(其结构与普通队列是一样的)

消息队列

我们将把数据放入到队列的那一方叫做生产者;将从消息队列中取数据的一方叫做消费者

2. 为什么要使用消息队列


以下我将通过几个简单的场景来简单说明我们为什么使用消息队列。

2.1 解耦

假设我们现在有一个环境数据生成系统A,系统A通过调用系统B和系统C的接口来向系统B、C来发送数据,场景一图如下:


场景1

即系统A在有新的环境数据生成时,会通过调用B、C系统的接口来将生成的数据发送给B、C。写成伪代码如下所示(此处不考虑用观察者模式实现解耦并实时通知观察者的情况):

public class SystemA {
 // 系统B和系统C的依赖
 SystemB systemB = new SystemB();
 SystemC systemC = new SystemC();
 // 系统A独有的数据
 private String environmentData= "data";
 public void doSomething() {
 // 通过调用接口发送数据
 systemB.SystemBNeed2do(environmentData);
 systemC.SystemCNeed2do(environmentData);
 }
}

这种情况下,会有以下问题:

  • 如果某一天系统B不需要这些数据了,让系统A的负责人将发送数据给他们的那一部分代码给改了,即注释掉systemB.SystemBNeed2do(environmentData);
  • 有新的系统D需要这些数据了,需要增加调用D系统接口来发送数据的代码;
  • 同时,系统A还需要考虑如果其余系统B、C、D的系统如果挂了怎么办,要不要重发。

从上面的场景可以发现,系统A与其他三个系统高度耦合了。我们试想如下场景二,系统A将最新的环境数据信息放到MQ中,哪个系统需要就可以订阅这个消息消费。如果某个系统不需要这些数据了,就取消对MQ消息的消费即可。这种场景下,A系统完全不需要去考虑将数据发送给谁,也不需要去维护之前发送数据的代码,不需要考虑其他系统是否调用成功、失败超时等情况。

场景2

小结
通过这种模式消息发布与订阅的模式,使得系统A与其他系统解耦。

2.2 异步

其实我仔细斟酌了一下异步与解耦的场景,发现其实异步与解耦是有一定关系的,我们使用同样的场景,只是我们考虑的面不同,场景三如下图所示。但我们现在考虑的面是时间效率。


场景3

假设系统A产生环境数据需要100ms,调用系统B、C、D的接口分别需要300ms、300ms、300ms,那么在类似场景一的设计方式时,这次请求所需要耗费的时间为100+300+300+300 = 1000ms = 1s。请求会随着需要环境数据的系统越来越多而使得请求响应越来越慢,这是用户不能忍受的,即类似我们去请求一个系统服务,我们主要想要的服务只是系统A生成的环境数据服务,而系统A这个时候却因为其它系统调用而使得这个服务请求响应过慢。

而如果是类似于如下场景时,我们的响应时间仅仅是产生消息的时间100ms。


场景4

小结

  • 同步场景下,整个请求需要耗时1s;
  • 异步场景下,请求只需要100ms。
2.3 削峰/限流

我们接着考虑如下场景,假设我们的系统A有个促销功能,大促销期间并发量较大,我们假设每秒可能有5k个请求。如下图。


场景5

一般的MySQL,每秒能处理2k个请求就差不多了,如果每秒5k个请求同时处理的话,可能会导致MySQL不可用,导致整个系统崩溃,用户也就没法使用MySQL了。但一过了促销期,每秒请求只有百来个,这个时候对系统几乎没有任何压力。

如果使用MQ,每秒5k个请求写入MQ,A系统可以根据自身的处理能力来决定每秒拉取的请求数。这样下来,在高峰期时系统A也不会挂掉。


场景6

这个短暂的高峰期积压是完全OK的。(消息队列是支持吞高吐量的,为此不用担心这个量的问题,同样,我们可以暂不考虑MQ挂掉的情况)。
系统A按照它能处理的速率来处理请求。

小结
通过将请求放在支持高吞吐量的MQ中来到达削峰/限流的效果。

2.4 其它应用场景

  • 日志处理:将大量日志存储到消息队列中(一般采用分布式消息队列kafka),解决大量日志传输的问题。其中,消息队列负责日志数据的接收,存储和转发;
  • 消息通讯:点对点通讯或聊天室通讯。

3. 使用消息队列会有什么优缺点


优点其实就是上文中谈到的,在特殊场景下的应用好处,解耦、异步与削峰等。

系统可用性
系统因为依赖与MQ消息队列这个服务,若这个服务崩溃了,那么我们的整个系统将不可用。为此往往我们都是通过集群/分布式部署来实现MQ高可用的。

系统复杂度
我们将数据写到消息队列上,就有可能会存在数据丢失的情况。以及我们如何保证消息没有被重复消费等问题。

一致性问题
A系统将请求写入到消息队列后就返回请求成功了,假设在多机部署的时候,系统B、C写库成功,假设D写入失败了,这种情况下就会产生数据不一致的问题。

4. 后语


总的来说,虽然引入消息队列有很多好处,但是也得针对它的缺点来引入其它技术方案和架构来规避这些问题,所以我们应该按照我们的实际需求与场景,来选择我们的技术方案。

本人水平有限,难免有错误或遗漏之处,望大家指正和谅解,欢迎评论留言。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容