編碼之外,一文搞懂什麼是消息隊列!

今天,我們一起來看看,消息隊列是個啥?

消息隊列是否瞭解?

消息隊列初步來看,是由“消息”和“隊列”組成,英文叫做:Message Queue,一般這些玩意都會根據英文名稱來個簡稱,而簡稱一般就是英文名字的首字母縮寫,所以消息隊列即MQ

可能你對消息隊列有點陌生,但是你一定聽過消息隊列四個字,而且還會聽過或者在其他地方見過比如RabbitMQ,還有RocketMQ,如果這些你都沒聽過,那你一定聽過Kafka吧,這些知識可能在你那裏都是高大上的概念,自己覺得目前還學不來這些知識……

所以,我覺得應該有相當一部分只是聽過這些名字,但是僅僅而已,再多一點的信息可能就不知道了,那麼從現在開始,跟隨慶哥,一起來學習消息隊列吧,同樣的,慶哥會用大白話給你講解這些晦澀難懂的概念與技術。

中間件是否瞭解

其實消息隊列屬於一種中間件,這個中間件,我想大部分應該也聽過,但是也不太清楚是個什麼玩意,其實吧,在編程世界裏啊,很多解決不了的問題,都可以加個中間件來搞定,中間件,名字已經很直白了,就是相當於一個橋樑,比如A與B有直接關係,但是現在A和B之間引入了一個c,那麼c就可以看做一箇中間件,A和B依然可以通信,只不過不是直接通信,要藉助c來實現了,畫個圖,簡單的就是這樣:

在這裏插入圖片描述

而消息隊列就是屬於一種中間件,充當了一個橋樑作用, 相當於在原有的基礎之上強塞了一個玩意過去,以後原有的需要做些什麼,可能就要經過這個新來的中間件了。

消息隊列到底是個啥?

那消息隊列有啥用嘞?以上,我們知道了消息隊列是個中間件,哪還有啥嘞?就知道箇中間件也不起作用啊,還是對消息隊列一臉懵逼吧,想要搞定消息隊列是個啥?我們得從字面意思上去拆解,首先,什麼是消息你知道嗎?

消息這個不多說, 屬於不言而喻的東西,那麼啥是隊列,這個可能就有人不清楚了,不過不用擔心,我之前特意寫過一篇講解隊列的文章,你可以去看看:輕輕鬆鬆學會棧和隊列(附有順序棧的實現思路分析)

加入你已經看了這篇文章了,也許現在你已經知道了啥是隊列,我相信,你知道的依舊是個概念,也就是隊列的那些特點啥的,比如是個數據結構啊,什麼先進先出啊,有什麼隊頭和隊尾之嘞的。

這些都是概念性的問題,如果你是第一次接觸隊列的話,我相信,你內心還是迷茫的,這都是啥啊,你可能會問。

其實吧,隊列是屬於一種數據結構,數據結構這玩意剛開始學習很玄學,不知道所以然,數據結構其實就是在告訴你,數據該怎麼進行存儲,按照一些特定的規則以及方式去儲存數據,簡單來說這就是數據結構在做的事情。

就拿數組來說,如果你需要用數組的話,那麼實際上就是取內存申請了一段連續的內存空間,這個連續就是一個特點,要求你這些數據必須連續存儲在這些內存中……

隊列其實也是一樣,說到底,就是告訴你怎麼在內存中存儲數據,記住這個先,那消息隊列,也是這樣,很直白的按照字面意思理解,就是存儲消息的隊列,所以啊,消息隊列就是用來存儲信息,然後其他可以從它這獲取信息。

總結的說,消息隊列是進行消息的收發,可以起到一個通信的作用,畢竟消息是可以傳遞信息的,你打個電話,發個短信,這都是在傳遞信息啊,這不都是通信嘛,這個應該不難理解!

所以記住,消息隊列:消息收發,通信

這麼一看,消息隊列好像就起到了一個通信的作用?當然不是,通信只是一部分,它所起到的作用絕對不僅僅如此。

我上面說了這麼多,其實就是在跟你掰扯,消息隊列是啥?不知道你清楚了沒有,如果別人問你,知道消息隊列嗎?你必須回答,知道啊,消息隊列,是一種中間件,進行消息的收發,可以解決一些通信問題……

當然,你這樣回答遠遠不夠,你還必須知道以下這些關於消息隊列的知識。

有哪些消息隊列

首先你得知道,消息隊列MQ是一個統稱,具體的有不同的產品,啥意思咧,就比如說水果,那還包括香蕉和蘋果嘞,所以,消息隊列有好幾種嘞,我這裏說幾種當下比較流行的,其實也就三種:

  1. RabbitMQ
  2. RocketMQ
  3. Kafka

這三種,上面也簡單提過,可能你們也聽說過,只是沒有具體的去學習過,那麼從現在開始,也就是看了我這次的分享這後,別人再問起消息隊列,最起碼你能夠把這三個給說出來,並且還能對他們挨個做下介紹。

RabbitMQ

這個消息隊列比較老牌了,這個俗稱兔子MQ,至於爲啥這樣說,你應該知道。

RabbitMQ在一開始是很強勢的,也就是曾經很輝煌,當然,現在也不賴,只不過由於一些後起之秀,光芒不勝從前了,畢竟後來的也很優秀,RabbitMQ它的特點你需要記住:

  1. 開箱即用
  2. 輕量級
  3. 易於部署和使用
  4. 支持靈活的路由配置
  5. 客戶端支持的編程語言是最多的(至少目前是)
  6. ……

知道以上幾個就差不多了,當然,你還得知道RabbitMQ的幾個不好地方:

  1. 使用Erlang語言編寫(這是個啥語言我之前真不知道,這就導致一個大問題,想要二次開發與擴展,以及遇到問題的話,解決的成本都比較高啊)
  2. 對消息堆積支持的不友好(消息隊列就是進行消息收發的啊,大量的消息扔進RabbitMQ的話,它的性能表現就不那麼好了)
  3. 性能相比較RocketMQ和Kafka是最差的

關於RabbitMQ,你目前就需要知道這些就行了,因爲每一種消息隊列產品都是值得我們單獨花時間學習和研究的,所以這裏我們肯定介紹不了那麼多,這個以後會單獨學習他們,到那時候再分享。

RocketMQ

這個就比較牛了,好像現在差不多都在用這個吧,不過還是分場景吧,不同的應用場景應該選擇不同的消息隊列,RocketMQ屬於明星產品啊,它是阿里巴巴搞出來的,後來捐贈給了Apache基金會,2017年成了其頂級項目,阿里內部也是使用的它。

可以說,RocketMQ是一款綜合變現都很不錯的消息隊列產品,無論是性能還是穩定性,亦或是可靠性,RocketMQ表現的都很不錯,反正吧,這傢伙是越來越首歡迎了。

那麼咱們來看看它的一些特點吧:

  1. 用java語言開發,好處多多啊
  2. 響應時延這塊優化的很好(就是響應時間優化的很短)
  3. 性能優越,比兔子MQ好

那要說它有什麼不好的地方,那可能就是因爲它是我們國人開發的,在於世界上其他優秀的產品協作的時候,集成和兼容性問題上可能有點不足,不過啊,這算得上是問題嗎?😂

Kafka

這個傢伙,我之前可是經常聽到它,它相比較前兩者,雖然都是消息隊列中間件,但是它似乎有點另類,就從名字上看,人家都是啥啥啥MQ,這傢伙直接叫做Kafka(卡夫卡),還是很有個性的。

它一開始是爲了用於處理海量日誌的,所以啊,它與大數據關係頗深,它在處理海量日誌啊,或者是監控信息,以及流計算這些的時候,無疑是最好的選擇。

而且Kafka可以說是與周邊開源產品兼容最好的一箇中間件,也就是說,幾乎所有的相關開源軟件系統都會優先支持Kafka。

另外它使用java和Scala編寫,在性能,穩定性和可靠性上也都表現優異,這麼一看,這傢伙好像是集萬衆寵愛於一身啊,妥妥的老大啊,各方面都很優異啊。

但是它對消息是進行異步批量進行處理的,這就帶來一個問題,延遲比較高,這點他是比不上RocketMQ。

因此嘞,這傢伙不太適合在線業務場景

該怎麼選擇這些消息隊列嘞?

經過對上面的集中流行的消息隊列中間件的介紹,你大致可以跟別人簡單介紹下他們,那麼接下來的問題就是該怎麼選擇他們的問題。

其實也很簡單,根據不同的應用場景和需求去選擇他們。

什麼場景下該選擇RabbitMQ,什麼場景下該選擇RocketMQ,什麼場景下又該選擇Kafka呢?

首先對於RabbitMQ,我們講到它的時候,可能最先想到的就是它的輕量,開箱即用易於維護,所以基於這個特點,如果你的項目需要用到消息隊列,但是消息隊列又不是你係統的主角,那麼RabbitMQ是一個不錯的選擇。

當然,如果對於你的系統,消息隊列扮演着重要的角色,對性能,穩定性以及可靠性等都有一定的要求,更重要的是你需要使用消息隊列來處理在線業務場景,那麼你最好選擇RocketMQ,因爲它優越的低延遲,以及優秀的穩定性絕對會給你給力的表現。

如果你是需要處理海量的信息,業務涉及大數據,流計算等,那麼這樣的情況下,Kafka無疑是最好的選擇了。

消息隊列的常見應用場景?

到了這裏你就該去思考下,碰到什麼樣的問題,你需要使用消息隊列呢?這也是常見的面試題,消息隊列有哪些常見應用場景,這個是你必須要知道的。

提到這個,熟悉消息隊列的可能立馬就會說出三個詞:異步,削峯和解耦,啥意思嘞?如果之前不瞭解消息隊列的話,聽到這三個,一定會覺得有那麼點東西啊,我竟然都不知道,對於屬於的而言,一聽就知道接下來你要講的是啥。

所以嘞,接下來我主要給那些之前還不知道的說道說道。

異步

這裏主要指的是服務的異步請求,啥意思嘞,一般提到這個,很多人都會提到秒殺系統,因爲秒殺系統一定會使用到消息隊列,也比較好用來解釋消息隊列的一些特性。

不過提到秒殺系統,估計有些人也是一臉懵逼,這也是經常聽說,但是覺得很高大上,自己又沒有學習的玩意啊,其實一個秒殺系統,我也沒有設計過,具體涉及的技術棧,我也不是很清楚,但是我知道這一點就夠了,最起碼夠我去理解消息隊列的異步使用場景了,那是啥嘞?

所謂的秒殺系統,其中必定有的就是在同一時間內,會有大量的服務請求過來。

知道這個,咱們就可以來看看這個服務異步了,秒殺系統中要處理的一個問題就是短時間內,有大量的請求過來,這個你得處理啊,不然服務器一時間承受不了這麼大的請求數量,那服務器會被搞死的,那怎麼辦嘞?

解決辦法也很簡單,那就是加入消息隊列,那爲啥要加入消息隊列啊,我們得來再看看這個秒殺系統,秒殺系統這個一般就是定一個時間點,或者時間段,某個火爆的商品開始揮淚大甩賣,我們人吶都是喜歡貪便宜的,所以這個必須得搶啊,於是都提前訂好鬧鐘,一到時間,裏面點擊立即購買,然後下單,然後成功搶到,然後付款,然後發貨……有的還會即時發消息給你,“恭喜你這個崽,成功搶到這次的商品……”

我們來簡單分析下這個流程,首先,你點擊立即購買,然後簡單點,就是你搶到了,讓你付款,接着提示你付款成功,然後給你發貨,發消息,但是你想過沒有,這個時候可不是你一個人做這些操作啊,可能有成千上萬個,這個時候這個商品服務系統就沒有那麼快了,可能你點了立即購買,遲遲不見付款界面,爲啥,因爲這個時候再處理其他用戶的請求。

這個當中你還得明白一點,就是在這個秒殺操作中,比如這個商品庫存就有1000個,但是現在有一萬人來搶,那麼當你點擊立即購買的時候,如果你網速夠快,你夠幸運搶到了,那麼其實在後臺,就會進行庫存鎖定,也就是剩餘庫存會減去你搶到的這些,然後會給你生成訂單,讓你付款,你可以想一下,當有很多人來做這個操作的時候,因爲其中會處理別人的請求,所以你的請求就不會立馬得到響應,可能這其中還有什麼可以用積分抵扣,那麼還要去做積分的相應扣減,可能還有什麼優惠券之類的,會員特權之類的啊,都會做相應的操作

說這麼多就是想說,你可能要等很久,頁面也沒有響應,你也不知道自己有沒有秒殺成功,所以啊這樣的話,用戶體驗就很差,你可能就要罵了“這什麼垃圾APP啊”。

怎麼解決嘞?你其實可以想想,這其中是不是隻要你的請求過來成功進行庫存鎖定,也就是確定有你這一份了,那麼剩下的相關操作,比如扣積分之類的,生成訂單啥的,其實可以先不用管,只要庫存一旦鎖定成功,就可以立馬給你返回“秒殺成功”,這樣豈不美滋滋。

那怎麼實現嘞,其實就是使用消息隊列,一旦你秒殺成功,成功進行庫存鎖定,這個時候就可以把請求的相關數據放進消息隊列中,然後給你返回結果,至於後續的積分,訂單甚至給你發短信,則有相應的系統去從消息隊列去拿到這個請求的數據,然後去處理,而這個其實並不要求你立馬完成。

這麼一來,我們就可以把大量的服務資源去處理這個秒殺請求,至於其他的後續操作則可以交由消息隊列去由其他系統進行異步操作

這有啥好處嘞,顯而易見的就是我們可以更快的接收到處理結果,而且整體系統的性能也提高了。

削峯

這個完整的叫做“削峯填谷”,聽起來很是高大上啊,其實我覺叫做流量控制更加好理解,啥意思嘞,還是拿這個秒殺系統來說,當短時間內大量秒殺請求過來的時候,服務器一時間處理不了這麼多請求,有可能把服務器給搞死。

這個時候我們可以加入消息隊列,管你來多少請求嘞,統統把這些請求給你放到消息隊列中,然後看我們服務器的處理能力,能夠處理多少,就從消息隊列中拿出,對於那些暫時沒法處理的請求,也很有可能就會發生請求超時,一般這種情況也就意味着你秒殺失敗了,那直接給用戶返回“秒殺失敗”的通知就可以了。

這樣就可以很好的避免,因爲大量請求而把我們的系統服務搞死的情況了。

但是這樣也會產生一些新的問題,比如之前有請求回來,都是我們的服務器去直接處理,而現在嘞,中間多了一個消息隊列,消息需要進去,我們的服務器需要從消息隊列中去拿,這樣一來,就增加了調用的複雜度,那麼相應的響應時間也就變長了,整體系統也變得比之前複雜了,這個也是你需要知道的。

這就是我們說的削峯了,其實還是叫流量控制比較好理解吧。

解耦

最後一個就是關於解耦了,這個我們有些朋友可能知道,啥是解耦,一般就是一些系統啥的,之間互相依賴,你需要我,我有需要它,你我他之間是高度依賴的,如果其中出現一個問題的話,那其他的也受到影響,那麼這個時候就需要解耦,解耦的目的就是把你我他隔離開來,大家互不影響。

舉個例子吧,比如我們下單這個操作,當你下單完成之後,可能還會有一些其他的操作,因爲這些操作都是需要得到你下單的數據之後才能進行相應的操作,這個時候他們之間就是高度依賴的,如果這些下單之後的相應系統有一些改變,那麼下單這個操作可能就需要做一些改變。

總的來說,下單之後的一些操作高度依賴下單這個動作,反過來,下單後的這些操作也間接影響着下單這個動作,這樣他們之間高度依賴,如果有什麼問題,可能都需要進行改動,也就是所謂的,牽一髮而動全身,好像是這麼說來着。

這肯定不行啊,怎麼解決嘞?那就是引入消息隊列來解決,也就是下單成功了,把下單的數據放進消息隊列,需要用到這個下單數據的其他系統,自動訂閱這個消息隊列,從消息隊列中去取數據,這麼一來下單和下單之後的一些操作就隔開了,下單隻管下單的,下單成功,就不管你後續的操作啥的,後面的其他系統如果需要這個下單數據,那就去消息隊列中去拿,下單這個本身才不管你們這些嘞。

其實吧,我覺得這個解耦和異步有點相像,不知道你們怎麼看?

使用消息隊列有什麼問題嗎?

我們上面嘮嘮叨叨的把消息隊列給說了說,覺得消息隊列很好用啊,那麼使用消息隊列有沒有什麼問題呢?

這個其實是很定的,作爲一種中間件,使用了消息隊列,那就意味着增加了系統的複雜性,除此之外,基於消息隊列的特點,它可能發生這麼些問題:

  1. 消息隊列這個中間件如果掛了怎麼整?
  2. 消息放進了消息隊列中,真的一定能放進去,會不會把我放進去的消息整丟了
  3. 會不會有重複的消息放進消息隊列?
  4. 如果消息隊列中的消息越放越多,而又不被消費,那麼消息堆積了咋整
  5. ……

等等吧,這些都是消息隊列會遇到的問題,可能有些人會問了,那麼這個怎麼解決啊,一般的主流的消息隊列產品肯定都考慮到了這些問題,而且也都做了相應的處理,你就比如RocketMQ來說,一般你做好相應的配置啥的,就不會出現消息丟失的情況。

也就是說,不同的消息隊列產品都有自己的應對辦法,具體是怎樣的,那就得看齊消息隊列本身了,這個以後我們再說,今天關於消息隊列的介紹就先到這裏。

有什麼問題,歡迎大家留言討論!

感謝閱讀

大學的時候選擇了自學Java,工作了發現吃了計算機基礎不好的虧,學歷不行這是沒辦法的事,只能後天彌補,於是在編碼之外開啓了自己的逆襲之路,不斷的學習Java核心知識,深入的研習計算機基礎知識,所有心得全部書寫成文,整理成有目錄的PDF,持續原創,PDF在公衆號持續更新,如果你也不甘平庸,那就與我一起在編碼之外,不斷成長吧!

其實這裏不僅有技術,更有那些技術之外的東西,比如,如何做一個精緻的程序員,而不是“屌絲”,程序員本身就是高貴的一種存在啊,難道不是嗎?

非常歡迎你的加入,未來的日子,編碼之外,有你有我,一起做一個人不傻,錢很多,活得久的快樂的程序員吧!

回覆關鍵字“PDF”,獲取技術文章合集,已整理好,帶有目錄,歡迎一起交流技術!

另外回覆“慶哥”,看慶哥給你準備的驚喜大禮包,只給首次關注的你哦!

任何問題,可以加慶哥微信:H653836923,另外,我有個交流羣,我會***不定期在羣裏分享學習資源,不定時福利***,感興趣的可以說下我邀請你!

對了,如果你是個Java小白的話,也可以加我微信,我相信你在學習的過程中一定遇到不少問題,或許我可以幫助你,畢竟我也是過來人了!

在這裏插入圖片描述

感謝各位大大的閱讀🥰

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章