国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

面試官問你什么是消息隊列?把這篇甩給他!

開發(fā) 后端
消息隊列不知道大家看到這個詞的時候,會不會覺得它是一個比較高端的技術(shù),反正我是覺得它好像是挺牛逼的。

[[262508]]

一、什么是消息隊列?

消息隊列不知道大家看到這個詞的時候,會不會覺得它是一個比較高端的技術(shù),反正我是覺得它好像是挺牛逼的。

消息隊列,一般我們會簡稱它為MQ(Message Queue),嗯,就是很直白的簡寫。

我們先不管消息(Message)這個詞,來看看隊列(Queue)。這一看,隊列大家應(yīng)該都熟悉吧。

隊列是一種先進(jìn)先出的數(shù)據(jù)結(jié)構(gòu)。

在Java里邊,已經(jīng)實(shí)現(xiàn)了不少的隊列了:

那為什么還需要消息隊列(MQ)這種中間件呢???

  •  到這里,大家可以先猜猜為什么要用消息隊列(MQ)這種中間件,下面會繼續(xù)補(bǔ)充。

消息隊列可以簡單理解為:把要傳輸?shù)臄?shù)據(jù)放在隊列中。

圖片來源:https://www.cloudamqp.com/blog/2014-12-03-what-is-message-queuing.html

科普:

  •  把數(shù)據(jù)放到消息隊列叫做生產(chǎn)者
  •  從消息隊列里邊取數(shù)據(jù)叫做消費(fèi)者

二、為什么要用消息隊列?

為什么要用消息隊列,也就是在問:用了消息隊列有什么好處。我們看看以下的場景

2.1 解耦

現(xiàn)在我有一個系統(tǒng)A,系統(tǒng)A可以產(chǎn)生一個userId

然后,現(xiàn)在有系統(tǒng)B和系統(tǒng)C都需要這個userId去做相關(guān)的操作

寫成偽代碼可能是這樣的: 

  1. public class SystemA {  
  2.     // 系統(tǒng)B和系統(tǒng)C的依賴  
  3.     SystemB systemB = new SystemB();  
  4.     SystemC systemC = new SystemC();  
  5.     // 系統(tǒng)A獨(dú)有的數(shù)據(jù)userId  
  6.     private String userId = "Java3y" 
  7.     public void doSomething() {  
  8.         // 系統(tǒng)B和系統(tǒng)C都需要拿著系統(tǒng)A的userId去操作其他的事  
  9.         systemB.SystemBNeed2do(userId);  
  10.         systemC.SystemCNeed2do(userId);  
  11.     }  

結(jié)構(gòu)圖如下:

ok,一切平安無事度過了幾個天。

某一天,系統(tǒng)B的負(fù)責(zé)人告訴系統(tǒng)A的負(fù)責(zé)人,現(xiàn)在系統(tǒng)B的SystemBNeed2do(String userId)這個接口不再使用了,讓系統(tǒng)A別去調(diào)它了。

于是,系統(tǒng)A的負(fù)責(zé)人說"好的,那我就不調(diào)用你了。",于是就把調(diào)用系統(tǒng)B接口的代碼給刪掉了: 

  1. public void doSomething() {  
  2.   // 系統(tǒng)A不再調(diào)用系統(tǒng)B的接口了  
  3.   //systemB.SystemBNeed2do(userId);  
  4.   systemC.SystemCNeed2do(userId);  

又過了幾天,系統(tǒng)D的負(fù)責(zé)人接了個需求,也需要用到系統(tǒng)A的userId,于是就跑去跟系統(tǒng)A的負(fù)責(zé)人說:"老哥,我要用到你的userId,你調(diào)一下我的接口吧"

于是系統(tǒng)A說:"沒問題的,這就搞"

然后,系統(tǒng)A的代碼如下: 

  1. public class SystemA {  
  2.     // 已經(jīng)不再需要系統(tǒng)B的依賴了  
  3.     // SystemB systemB = new SystemB();  
  4.     // 系統(tǒng)C和系統(tǒng)D的依賴  
  5.     SystemC systemC = new SystemC();  
  6.     SystemD systemD = new SystemD();  
  7.     // 系統(tǒng)A獨(dú)有的數(shù)據(jù)  
  8.     private String userId = "Java3y" 
  9.     public void doSomething() {  
  10.         // 已經(jīng)不再需要系統(tǒng)B的依賴了  
  11.         //systemB.SystemBNeed2do(userId);  
  12.         // 系統(tǒng)C和系統(tǒng)D都需要拿著系統(tǒng)A的userId去操作其他的事  
  13.         systemC.SystemCNeed2do(userId);  
  14.         systemD.SystemDNeed2do(userId);  
  15.     }  

時間飛逝:

  •  又過了幾天,系統(tǒng)E的負(fù)責(zé)人過來了,告訴系統(tǒng)A,需要userId。
  •  又過了幾天,系統(tǒng)B的負(fù)責(zé)人過來了,告訴系統(tǒng)A,還是重新掉那個接口吧。
  •  又過了幾天,系統(tǒng)F的負(fù)責(zé)人過來了,告訴系統(tǒng)A,需要userId。
  •  ……

于是系統(tǒng)A的負(fù)責(zé)人,每天都被這給騷擾著,改來改去,改來改去…….

還有另外一個問題,調(diào)用系統(tǒng)C的時候,如果系統(tǒng)C掛了,系統(tǒng)A還得想辦法處理。如果調(diào)用系統(tǒng)D時,由于網(wǎng)絡(luò)延遲,請求超時了,那系統(tǒng)A是反饋fail還是重試??

***,系統(tǒng)A的負(fù)責(zé)人,覺得隔一段時間就改來改去,沒意思,于是就跑路了。

然后,公司招來一個大佬,大佬經(jīng)過幾天熟悉,上來就說:將系統(tǒng)A的userId寫到消息隊列中,這樣系統(tǒng)A就不用經(jīng)常改動了。為什么呢?下面我們來一起看看:

系統(tǒng)A將userId寫到消息隊列中,系統(tǒng)C和系統(tǒng)D從消息隊列中拿數(shù)據(jù)。這樣有什么好處?

  •  系統(tǒng)A只負(fù)責(zé)把數(shù)據(jù)寫到隊列中,誰想要或不想要這個數(shù)據(jù)(消息),系統(tǒng)A一點(diǎn)都不關(guān)心。
  •  即便現(xiàn)在系統(tǒng)D不想要userId這個數(shù)據(jù)了,系統(tǒng)B又突然想要userId這個數(shù)據(jù)了,都跟系統(tǒng)A無關(guān),系統(tǒng)A一點(diǎn)代碼都不用改。
  •  系統(tǒng)D拿userId不再經(jīng)過系統(tǒng)A,而是從消息隊列里邊拿。系統(tǒng)D即便掛了或者請求超時,都跟系統(tǒng)A無關(guān),只跟消息隊列有關(guān)。

這樣一來,系統(tǒng)A與系統(tǒng)B、C、D都解耦了。

2.2 異步

我們再來看看下面這種情況:系統(tǒng)A還是直接調(diào)用系統(tǒng)B、C、D

代碼如下: 

  1. public class SystemA {  
  2.     SystemB systemB = new SystemB();  
  3.     SystemC systemC = new SystemC();  
  4.     SystemD systemD = new SystemD();  
  5.     // 系統(tǒng)A獨(dú)有的數(shù)據(jù)  
  6.     private String userId ;  
  7.     public void doOrder() {  
  8.         // 下訂單  
  9.           userId = this.order();  
  10.         // 如果下單成功,則安排其他系統(tǒng)做一些事    
  11.         systemB.SystemBNeed2do(userId);  
  12.         systemC.SystemCNeed2do(userId);  
  13.         systemD.SystemDNeed2do(userId);  
  14.     }  

假設(shè)系統(tǒng)A運(yùn)算出userId具體的值需要50ms,調(diào)用系統(tǒng)B的接口需要300ms,調(diào)用系統(tǒng)C的接口需要300ms,調(diào)用系統(tǒng)D的接口需要300ms。那么這次請求就需要50+300+300+300=950ms

并且我們得知,系統(tǒng)A做的是主要的業(yè)務(wù),而系統(tǒng)B、C、D是非主要的業(yè)務(wù)。比如系統(tǒng)A處理的是訂單下單,而系統(tǒng)B是訂單下單成功了,那發(fā)送一條短信告訴具體的用戶此訂單已成功,而系統(tǒng)C和系統(tǒng)D也是處理一些小事而已。

那么此時,為了提高用戶體驗(yàn)和吞吐量,其實(shí)可以異步地調(diào)用系統(tǒng)B、C、D的接口。所以,我們可以弄成是這樣的:

系統(tǒng)A執(zhí)行完了以后,將userId寫到消息隊列中,然后就直接返回了(至于其他的操作,則異步處理)。

  •  本來整個請求需要用950ms(同步)
  •  現(xiàn)在將調(diào)用其他系統(tǒng)接口異步化,從請求到返回只需要100ms(異步)

(例子可能舉得不太好,但我覺得說明到點(diǎn)子上就行了,見諒。)

2.3削峰/限流

我們再來一個場景,現(xiàn)在我們每個月要搞一次大促,大促期間的并發(fā)可能會很高的,比如每秒3000個請求。假設(shè)我們現(xiàn)在有兩臺機(jī)器處理請求,并且每臺機(jī)器只能每次處理1000個請求。

那多出來的1000個請求,可能就把我們整個系統(tǒng)給搞崩了…所以,有一種辦法,我們可以寫到消息隊列中:

系統(tǒng)B和系統(tǒng)C根據(jù)自己的能夠處理的請求數(shù)去消息隊列中拿數(shù)據(jù),這樣即便有每秒有8000個請求,那只是把請求放在消息隊列中,去拿消息隊列的消息由系統(tǒng)自己去控制,這樣就不會把整個系統(tǒng)給搞崩。

三、使用消息隊列有什么問題?

經(jīng)過我們上面的場景,我們已經(jīng)可以發(fā)現(xiàn),消息隊列能做的事其實(shí)還是蠻多的。

說到這里,我們先回到文章的開頭,"明明JDK已經(jīng)有不少的隊列實(shí)現(xiàn)了,我們還需要消息隊列中間件呢?"其實(shí)很簡單,JDK實(shí)現(xiàn)的隊列種類雖然有很多種,但是都是簡單的內(nèi)存隊列。為什么我說JDK是簡單的內(nèi)存隊列呢?下面我們來看看要實(shí)現(xiàn)消息隊列(中間件)可能要考慮什么問題。

3.1高可用

無論是我們使用消息隊列來做解耦、異步還是削峰,消息隊列肯定不能是單機(jī)的。試著想一下,如果是單機(jī)的消息隊列,萬一這臺機(jī)器掛了,那我們整個系統(tǒng)幾乎就是不可用了。

所以,當(dāng)我們項(xiàng)目中使用消息隊列,都是得集群/分布式的。要做集群/分布式就必然希望該消息隊列能夠提供現(xiàn)成的支持,而不是自己寫代碼手動去實(shí)現(xiàn)。

3.2 數(shù)據(jù)丟失問題

我們將數(shù)據(jù)寫到消息隊列上,系統(tǒng)B和C還沒來得及取消息隊列的數(shù)據(jù),就掛掉了。如果沒有做任何的措施,我們的數(shù)據(jù)就丟了。

學(xué)過Redis的都知道,Redis可以將數(shù)據(jù)持久化磁盤上,萬一Redis掛了,還能從磁盤從將數(shù)據(jù)恢復(fù)過來。同樣地,消息隊列中的數(shù)據(jù)也需要存在別的地方,這樣才盡可能減少數(shù)據(jù)的丟失。

那存在哪呢?

  •  磁盤?
  •  數(shù)據(jù)庫?
  •  Redis?
  •  分布式文件系統(tǒng)?

同步存儲還是異步存儲?

3.3消費(fèi)者怎么得到消息隊列的數(shù)據(jù)?

消費(fèi)者怎么從消息隊列里邊得到數(shù)據(jù)?有兩種辦法:

  •  生產(chǎn)者將數(shù)據(jù)放到消息隊列中,消息隊列有數(shù)據(jù)了,主動叫消費(fèi)者去拿(俗稱push)
  •  消費(fèi)者不斷去輪訓(xùn)消息隊列,看看有沒有新的數(shù)據(jù),如果有就消費(fèi)(俗稱pull)

3.4其他

除了這些,我們在使用的時候還得考慮各種的問題:

  •  消息重復(fù)消費(fèi)了怎么辦啊?
  •  我想保證消息是絕對有順序的怎么做?
  •  ……..

雖然消息隊列給我們帶來了那么多的好處,但同時我們發(fā)現(xiàn)引入消息隊列也會提高系統(tǒng)的復(fù)雜性。市面上現(xiàn)在已經(jīng)有不少消息隊列輪子了,每種消息隊列都有自己的特點(diǎn),選取哪種MQ還得好好斟酌。

***

本文主要講解了什么是消息隊列,消息隊列可以為我們帶來什么好處,以及一個消息隊列可能會涉及到哪些問題。希望給大家?guī)硪欢ǖ膸椭?/p>

 

 

責(zé)任編輯:龐桂玉 來源: Java編程
相關(guān)推薦

2020-04-20 13:11:21

HashMap底層存儲

2019-09-19 14:03:32

B樹節(jié)點(diǎn)數(shù)據(jù)結(jié)構(gòu)

2021-02-22 13:32:19

MySQLSQL索引

2021-03-08 12:47:42

MySQL查詢數(shù)據(jù)

2021-03-08 10:25:37

MySQL數(shù)據(jù)庫索引

2022-05-23 09:41:27

分庫分表數(shù)據(jù)庫算法

2025-04-09 00:00:55

2022-09-26 10:09:08

MVCC控制并發(fā)

2020-06-22 11:50:38

TCPIP協(xié)議

2020-06-12 09:40:32

消息隊列Java線程

2021-09-07 10:44:33

Java 注解開發(fā)

2023-12-11 08:32:58

數(shù)據(jù)庫DruidDBA

2025-11-20 06:10:00

2018-08-07 16:01:32

synchronizevolatilefinal

2020-04-28 09:15:58

HashMapJava數(shù)組

2025-11-11 09:25:19

2020-08-17 07:40:19

消息隊列

2024-05-29 14:34:07

2025-10-20 04:00:00

2021-12-08 06:53:29

面試動態(tài)代理
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

成人免费视屏| 69堂免费精品视频在线播放| 9l视频自拍九色9l视频成人| 日本不卡123| 欧美午夜片在线看| 97香蕉久久夜色精品国产| 日本一级黄视频| 九七伦理97伦理| 日本在线精品| 国产精品国产自产拍高清av| 中文字幕一区二区在线观看| 亚洲国产另类精品专区| 午夜欧美大尺度福利影院在线看| 亚洲欧美自拍偷拍| 91麻豆精东视频| 欧美性生活久久| 97久草视频| 国产日韩精品在线| 国产91在线视频观看| 激情国产在线| 日韩1区2区3区| 91精品欧美综合在线观看最新| 97在线中文字幕| 韩国福利在线| 在线一区视频| 日韩三级视频在线看| 新呦u视频一区二区| 182在线视频观看| av在线这里只有精品| 国产一区二区三区精品视频| 另类亚洲自拍| 九九久久精品视频| 蜜桃一区二区三区在线| 欧美在线一区二区三区| 国产伦精品一区二区三区照片91 | 高清免费成人av| 精品成人私密视频| 特级毛片在线免费观看| 四虎地址8848精品| 国产精品家庭影院| 国产91色在线|免| 欧美偷拍视频| 日韩av中文字幕一区二区| 欧美日韩一区二区三区在线| 国内精品久久国产| 成人资源www网在线最新版| 日韩电影在线看| 精品sm捆绑视频| 日韩在线综合网| 法国空姐在线观看免费| 国产69精品久久app免费版| 免费久久99精品国产自在现线| 日韩国产欧美精品一区二区三区| 日韩成人手机在线| 日韩国产91| 精品国产91乱高清在线观看| 欧美二级三级| 亚洲一区二区三区在线免费| 午夜久久电影网| 亚洲国产日韩综合一区| 9l视频自拍九色9l视频成人| 欧美激情一区二区三区不卡| 国产欧美日韩综合精品| 中文产幕区在线观看 | 成人av在线一区二区| 国产欧美日韩中文字幕| 污视频网站在线免费| 激情欧美一区二区| 日韩成人中文字幕| 男人的天堂www| 亚洲欧美日韩高清在线| 91精品在线麻豆| 在线观看国产一级片| 三上悠亚在线免费观看| 午夜一区不卡| 国产精品成人观看视频国产奇米| 污片在线免费观看| 国产午夜久久久久| 欧美一级日本a级v片| 婷婷综合电影| 在线一区二区日韩| 第四色亚洲色图| 国产剧情在线观看一区二区| 国产精品旅馆在线| 亚洲成人一区在线观看| 中文字幕一区日韩精品欧美| 亚洲精品中文字幕在线| 羞羞视频在线观看一区二区| 911国产精品| 国产h色视频在线观看| 蜜臀av性久久久久蜜臀aⅴ| 久久久91精品| 五月婷婷在线观看| 亚洲男女毛片无遮挡| 免费看欧美一级片| 欧美一级二区| 欧美视频小说| 成人午夜av| 久久人人爽人人爽人人片av高请 | 日韩最新中文字幕| 99久久久久| 中文字幕成人精品久久不卡| 好紧好硬好湿我太爽了| 老司机精品视频一区二区三区| 国产精品视频xxx| 国产精品成人国产| 国产婷婷成人久久av免费高清| 福利网站在线观看| 精品国产乱码久久久久久虫虫漫画 | 国产亚洲精彩久久| 一区二区三区精品99久久| 性感女国产在线| 亚洲另类激情图| 变态调教一区二区三区| 精品免费日韩av| 素人av在线| 欧美日本韩国一区| 国产又色又爽又黄刺激在线视频| 亚洲精品电影久久久| 欧美片第1页| 亚洲欧洲日韩国产| 伊人久久噜噜噜躁狠狠躁| 免费91在线视频| 日韩a级大片| 久久久伊人欧美| 成人在线中文| 久久99精品久久久久久动态图| 婷婷五月色综合| 欧美国产精品一区| 欧美老熟妇喷水| 日韩激情中文字幕| 久久视频在线直播| 麻豆影视在线| 国产一区二区三区久久久| 亚洲欧美中文日韩在线| gogo高清在线播放免费| 日韩精品极品视频免费观看| 日本不卡网站| 最新国产精品拍自在线播放| 小h片在线观看| 97超级碰碰人国产在线观看| 在线日韩网站| 国产精品12| 国产成人精品综合在线观看| 国产亚洲欧美在线视频| 亚洲一区二区四区蜜桃| 成人77777| 啊v视频在线一区二区三区| 欧美残忍xxxx极端| 好色先生视频污| 国产风韵犹存在线视精品| 欧美激情成人网| 91美女蜜桃在线| 色佬视频在线观看| 欧美日韩国产色视频| 成人在线高清视频| 午夜精品久久久久久久99水蜜桃| 欧美自拍小视频| 日韩高清不卡一区| 成人情趣片在线观看免费| 理论片一区二区在线| 欧美一区二区免费观在线| а√最新版在线天堂| 免费在线一区观看| 国产精品自拍偷拍| 亚洲免费网址| 亚洲aⅴ天堂av在线电影软件| 99久久夜色精品国产网站| 日本在线丨区| 中文字幕亚洲一区| 久久精品人人| 香蕉视频免费在线| 97婷婷大伊香蕉精品视频| 国产一区二区三区在线观看免费视频| 日本午夜免费福利视频| 久久亚洲成人精品| 美女视频黄 久久| 可以在线观看的av| 国产精品成人v| 成人av动漫在线| 日本孕妇大胆孕交无码| 亚洲自拍另类欧美丝袜| 国产色产综合色产在线视频| 九色porny自拍视频在线播放| 国产在线精品一区| 亚洲va韩国va欧美va精品 | 午夜综合激情| 免费黄网站在线观看| 久久久久久久久久久91| 欧美日韩18| 香蕉影院在线| 国产综合在线观看视频| 久久久久久久久久久黄色| 日韩三级免费| 亚洲3p在线观看| 黄色成人美女网站| 久久久久久亚洲精品| 中文有码一区| 97avcom| 成人羞羞网站入口|