消息隊(duì)列應(yīng)用場景介紹
一、什么是隊(duì)列
隊(duì)列(Queue)是一種常見的數(shù)據(jù)結(jié)構(gòu),其最大的特點(diǎn)就是先進(jìn)先出(First In First Out),作為最基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu),隊(duì)列應(yīng)用很廣泛。比如火車站排隊(duì)買票等等??梢杂孟聢D表示隊(duì)列:
其中a1、a2、an表示隊(duì)列中的數(shù)據(jù)。數(shù)據(jù)從隊(duì)尾入隊(duì)列,然后從隊(duì)頭出隊(duì)列。
二、什么是消息隊(duì)列
消息隊(duì)列(Message Queue)是一種使用隊(duì)列(Queue)作為底層存儲(chǔ)數(shù)據(jù)結(jié)構(gòu),可以用于解決不同進(jìn)程與應(yīng)用程序之間通訊的分布式消息容器,也可以稱為消息中間件。
目前比較常用的消息隊(duì)列有ActiveMQ、RabbitMQ、Kafka、RocketMQ、Redis等。
消息隊(duì)列和隊(duì)列有什么區(qū)別呢?
唯一的區(qū)別在于入隊(duì)列的時(shí)候稱為生產(chǎn)者,出隊(duì)列的時(shí)候稱為消費(fèi)者。
三、消息隊(duì)列應(yīng)用場景
消息隊(duì)列應(yīng)用場景非常廣泛,下面我們列舉比較常見的幾個(gè)場景
1、分布式場景
1.1、異步處理
一般我們寫的程序都是按照順序執(zhí)行的(即同步的方式)。比如電商系統(tǒng)中訂單的例子,其執(zhí)行順序如下:
用戶提交訂單。訂單完成以后增加積分。發(fā)生積分變動(dòng)的短信通知。
可以用下面的流程圖表示:
如果按照上面的順序執(zhí)行,假如每個(gè)服務(wù)都需要花費(fèi)一秒,那么客戶端就要花費(fèi)3秒的時(shí)間。對(duì)于用戶來說,3秒的時(shí)間顯然是不能忍受的,那么我們?cè)撊绾谓鉀Q呢?我們可以使用異步的方式來解決這個(gè)問題,看下面一張流程圖:
按照這種方式,積分服務(wù)和短信服務(wù)使用線程異步的方式進(jìn)行操作,那么客戶端只需要花費(fèi)1秒的時(shí)間就可以完成了。但是,這種異步的方式會(huì)帶來另外的問題:并發(fā)量降低。因?yàn)榉e分服務(wù)和短信服務(wù)都需要在訂單服務(wù)里面開啟線程,開啟的線程多了,會(huì)導(dǎo)致客戶端訪問訂單服務(wù)的并發(fā)量降低,可能導(dǎo)致客戶端提交訂單的實(shí)際時(shí)間會(huì)超過1秒鐘。那么如何解決異步帶來的問題呢?那就是使用消息隊(duì)列,看下面的流程圖:
在上面的流程中,我們?cè)黾恿艘粋€(gè)消息隊(duì)列的角色,首先由客戶端提交訂單,然后把訂單寫入到消息隊(duì)列,積分服務(wù)和短信服務(wù)同時(shí)去消費(fèi)消息隊(duì)列里面的消息,這種方式不需要訂單服務(wù)在額外的開啟異步線程,客戶端可以實(shí)現(xiàn)真正的耗時(shí)1秒。
1.2、應(yīng)用解耦
我們還是以電商系統(tǒng)為例進(jìn)行講解,先看下面的流程圖:
上圖的業(yè)務(wù)邏輯:客戶端發(fā)起一個(gè)創(chuàng)建訂單的請(qǐng)求,創(chuàng)建訂單的時(shí)候,我們要先獲取庫存,然后在去扣減庫存,這樣訂單系統(tǒng)和庫存系統(tǒng)就形成了非常緊密的依賴關(guān)系。假如這時(shí)候庫存系統(tǒng)發(fā)生了宕機(jī),由于訂單系統(tǒng)依賴于庫存系統(tǒng),這時(shí)候訂單系統(tǒng)將不能使用。那么如何解決呢?
看下面使用消息隊(duì)列的流程圖:
在上面的流程中,我們加入了消息隊(duì)列。首先客戶端發(fā)起創(chuàng)建訂單的請(qǐng)求,訂單的消息寫入到消息隊(duì)列里面,然后庫存系統(tǒng)去消息隊(duì)列里面訂閱消息,最后異步的去更新庫存系統(tǒng)。如果庫存系統(tǒng)發(fā)生了宕機(jī),由于訂單系統(tǒng)不直接依賴于庫存系統(tǒng),所以訂單系統(tǒng)可以正常的響應(yīng)客戶端的請(qǐng)求。這樣就實(shí)現(xiàn)了應(yīng)用解耦。
1.3、流量削峰
對(duì)于高并發(fā)的系統(tǒng)來說,在訪問高峰時(shí),突發(fā)的流量就像洪水般涌向應(yīng)用系統(tǒng),尤其是一些高并發(fā)寫操作,隨時(shí)會(huì)導(dǎo)致數(shù)據(jù)庫服務(wù)器癱瘓,無法繼續(xù)提供服務(wù)。
而引入消息隊(duì)列則可以減少突發(fā)流量對(duì)應(yīng)用系統(tǒng)的沖擊。消費(fèi)隊(duì)列就像“水庫”一樣,攔截上游的洪水,削減進(jìn)入下游河道的洪峰流量,從而達(dá)到減免洪水災(zāi)害的目的。
在這方面最常見的例子就是秒殺系統(tǒng),一般秒殺活動(dòng)瞬間流量很高,如果流量全部涌向秒殺系統(tǒng),會(huì)壓垮秒殺系統(tǒng),通過引入消息隊(duì)列,可以有效緩沖突發(fā)流量,達(dá)到“削峰”的作用。
我們使用秒殺的場景來描述流量削峰,先看下面一張流程圖:
在上面的流程中,我們把秒殺服務(wù)稱為上游服務(wù),訂單服務(wù)、庫存服務(wù)、余額服務(wù)統(tǒng)稱為下游服務(wù)??蛻舳税l(fā)起秒殺的請(qǐng)求,秒殺服務(wù)收到客戶端發(fā)送的請(qǐng)求以后,創(chuàng)建訂單,修改庫存,扣減余額,這是秒殺的基本業(yè)務(wù)場景。
假如下游服務(wù)只能同時(shí)處理1000個(gè)并發(fā)請(qǐng)求,上游服務(wù)可以處理10000個(gè)并發(fā)請(qǐng)求,而客戶端發(fā)起了10000個(gè)請(qǐng)求,超出了下游服務(wù)可以處理的并發(fā)量,所以會(huì)導(dǎo)致下游服務(wù)發(fā)生宕機(jī)。這時(shí)就可以加入消息隊(duì)列來解決宕機(jī)的問題。看下面加入消息隊(duì)列的流程圖:
我們?cè)谏厦娴牧鞒虉D中加入了消息隊(duì)列,描述服務(wù)接收到客戶端發(fā)送的10000個(gè)請(qǐng)求以后,把所有的請(qǐng)求都寫入到消息隊(duì)列中,然后下游服務(wù)去訂閱消息隊(duì)列里面的秒殺請(qǐng)求,然后在去執(zhí)行自己的業(yè)務(wù)邏輯操作。
我們舉個(gè)簡單的例子,上游服務(wù)還是能處理10000個(gè)并發(fā)請(qǐng)求,下游服務(wù)還是只能處理1000個(gè)并發(fā)請(qǐng)求,那么這時(shí)候我們?cè)谙㈥?duì)列里面會(huì)允許存1000個(gè)并發(fā)請(qǐng)求。上游的秒殺服務(wù)接收到10000個(gè)并發(fā)請(qǐng)求,而消息隊(duì)列里面只能存1000個(gè)請(qǐng)求,多余的請(qǐng)求就不會(huì)存入到消息隊(duì)列里面,直接返回給客戶端提示“系統(tǒng)繁忙,請(qǐng)稍后!”。這就是所謂的流量削峰場景。這是由下游服務(wù)可以處理的并發(fā)量決定的。由于下游服務(wù)只能處理1000個(gè)并發(fā)請(qǐng)求,所以消息隊(duì)列里面只能存1000個(gè)秒殺,多余的秒殺請(qǐng)求全部返回客戶端提示。這樣就保證了下游服務(wù)的正常響應(yīng),不會(huì)導(dǎo)致下游服務(wù)發(fā)生宕機(jī),提高了系統(tǒng)的可用性。
2、日志場景
優(yōu)化日志傳輸
為了程序的健壯性,我們一般會(huì)在程序中添加各種記錄日志的功能,比如錯(cuò)誤日志、操作日志等等,看下面一張流程圖:
上面的流程圖是同步記錄日志的流程。使用同步記錄日志的流程,會(huì)使得整個(gè)流程花費(fèi)的時(shí)間增多,而且也會(huì)容易造成業(yè)務(wù)系統(tǒng)宕機(jī)(如果數(shù)據(jù)庫損壞了,向數(shù)據(jù)庫記錄日志的操作將會(huì)產(chǎn)生錯(cuò)誤)。我們可以使用消息隊(duì)列的方式優(yōu)化日志的傳輸。看下面的流程圖:
加入了消息隊(duì)列以后,可以縮短系統(tǒng)花費(fèi)的時(shí)間,而且也可以達(dá)到應(yīng)用系統(tǒng)解耦的功能。
3、及時(shí)通訊場景
聊天室
消息隊(duì)列最主要功能是收發(fā)消息,其內(nèi)部有高效的通訊機(jī)制,因此非常適合用于消息通訊。
我們可以基于消息隊(duì)列開發(fā)點(diǎn)對(duì)點(diǎn)的聊天系統(tǒng),也可以開發(fā)廣播系統(tǒng),用于將消息廣播給大量接收者。
到此這篇關(guān)于消息隊(duì)列應(yīng)用場景的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- asp.net通過消息隊(duì)列處理高并發(fā)請(qǐng)求(以搶小米手機(jī)為例)
- C#調(diào)用RabbitMQ實(shí)現(xiàn)消息隊(duì)列的示例代碼
- RabbitMQ延遲隊(duì)列及消息延遲推送實(shí)現(xiàn)詳解
- 使用 Redis 流實(shí)現(xiàn)消息隊(duì)列的代碼
- 使用MQ消息隊(duì)列的優(yōu)缺點(diǎn)詳解
- Python進(jìn)程間通信Queue消息隊(duì)列用法分析
- .NetCore利用BlockingCollection實(shí)現(xiàn)簡易消息隊(duì)列
- .net msmq消息隊(duì)列實(shí)例詳解
- 深入理解redis分布式鎖和消息隊(duì)列
- RabbitMQ .NET消息隊(duì)列使用詳解
相關(guān)文章
Trie樹_字典樹(字符串排序)簡介及實(shí)現(xiàn)
有時(shí),我們會(huì)碰到對(duì)字符串的排序,若采用一些經(jīng)典的排序算法,則時(shí)間復(fù)雜度一般為O(n*lgn),但若采用Trie樹,則時(shí)間復(fù)雜度僅為O(n)2014-03-03百度HI QQ和MSN 阿里旺旺貿(mào)易通MSN在線客服在線聊天代碼
有時(shí)候業(yè)務(wù)需要,需要讓客戶更方便的與我們溝通,就可以參考下面的代碼。2010-04-04會(huì)員下線加積分,實(shí)現(xiàn)原理分享(有時(shí)間限制)
當(dāng)某個(gè)用戶發(fā)出一個(gè)邀請(qǐng)后,另一個(gè)用戶通過這個(gè)鏈接進(jìn)行網(wǎng)站后,為發(fā)這個(gè)鏈接的用戶加10個(gè)積分。2011-09-09微信小程序(微信應(yīng)用號(hào))開發(fā)工具0.9版安裝詳細(xì)教程
這篇文章主要介紹了微信小程序(微信應(yīng)用號(hào))開發(fā)工具0.9版安裝詳細(xì)教程的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-09-09so easy!10行代碼寫個(gè)"狗屁不通"文章生成器功能
這篇文章主要介紹了通過10行代碼寫個(gè)"狗屁不通"文章生成器功能,真的超級(jí)簡單,感興趣的朋友跟隨腳本之家小編一起看看吧2020-01-01