網(wǎng)站首頁 編程語言 正文
一、什么是隊列
隊列(Queue)是一種常見的數(shù)據(jù)結(jié)構(gòu),其最大的特點就是先進(jìn)先出(First In First Out),作為最基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu),隊列應(yīng)用很廣泛。比如火車站排隊買票等等。可以用下圖表示隊列:
其中a1、a2、an表示隊列中的數(shù)據(jù)。數(shù)據(jù)從隊尾入隊列,然后從隊頭出隊列。
二、什么是消息隊列
消息隊列(Message Queue)是一種使用隊列(Queue)作為底層存儲數(shù)據(jù)結(jié)構(gòu),可以用于解決不同進(jìn)程與應(yīng)用程序之間通訊的分布式消息容器,也可以稱為消息中間件。
目前比較常用的消息隊列有ActiveMQ、RabbitMQ、Kafka、RocketMQ、Redis等。
消息隊列和隊列有什么區(qū)別呢?
唯一的區(qū)別在于入隊列的時候稱為生產(chǎn)者,出隊列的時候稱為消費者。
三、消息隊列應(yīng)用場景
消息隊列應(yīng)用場景非常廣泛,下面我們列舉比較常見的幾個場景
1、分布式場景
1.1、異步處理
一般我們寫的程序都是按照順序執(zhí)行的(即同步的方式)。比如電商系統(tǒng)中訂單的例子,其執(zhí)行順序如下:
用戶提交訂單。訂單完成以后增加積分。發(fā)生積分變動的短信通知。
可以用下面的流程圖表示:
如果按照上面的順序執(zhí)行,假如每個服務(wù)都需要花費一秒,那么客戶端就要花費3秒的時間。對于用戶來說,3秒的時間顯然是不能忍受的,那么我們該如何解決呢?我們可以使用異步的方式來解決這個問題,看下面一張流程圖:
按照這種方式,積分服務(wù)和短信服務(wù)使用線程異步的方式進(jìn)行操作,那么客戶端只需要花費1秒的時間就可以完成了。但是,這種異步的方式會帶來另外的問題:并發(fā)量降低。因為積分服務(wù)和短信服務(wù)都需要在訂單服務(wù)里面開啟線程,開啟的線程多了,會導(dǎo)致客戶端訪問訂單服務(wù)的并發(fā)量降低,可能導(dǎo)致客戶端提交訂單的實際時間會超過1秒鐘。那么如何解決異步帶來的問題呢?那就是使用消息隊列,看下面的流程圖:
在上面的流程中,我們增加了一個消息隊列的角色,首先由客戶端提交訂單,然后把訂單寫入到消息隊列,積分服務(wù)和短信服務(wù)同時去消費消息隊列里面的消息,這種方式不需要訂單服務(wù)在額外的開啟異步線程,客戶端可以實現(xiàn)真正的耗時1秒。
1.2、應(yīng)用解耦
我們還是以電商系統(tǒng)為例進(jìn)行講解,先看下面的流程圖:
上圖的業(yè)務(wù)邏輯:客戶端發(fā)起一個創(chuàng)建訂單的請求,創(chuàng)建訂單的時候,我們要先獲取庫存,然后在去扣減庫存,這樣訂單系統(tǒng)和庫存系統(tǒng)就形成了非常緊密的依賴關(guān)系。假如這時候庫存系統(tǒng)發(fā)生了宕機,由于訂單系統(tǒng)依賴于庫存系統(tǒng),這時候訂單系統(tǒng)將不能使用。那么如何解決呢?
看下面使用消息隊列的流程圖:
在上面的流程中,我們加入了消息隊列。首先客戶端發(fā)起創(chuàng)建訂單的請求,訂單的消息寫入到消息隊列里面,然后庫存系統(tǒng)去消息隊列里面訂閱消息,最后異步的去更新庫存系統(tǒng)。如果庫存系統(tǒng)發(fā)生了宕機,由于訂單系統(tǒng)不直接依賴于庫存系統(tǒng),所以訂單系統(tǒng)可以正常的響應(yīng)客戶端的請求。這樣就實現(xiàn)了應(yīng)用解耦。
1.3、流量削峰
對于高并發(fā)的系統(tǒng)來說,在訪問高峰時,突發(fā)的流量就像洪水般涌向應(yīng)用系統(tǒng),尤其是一些高并發(fā)寫操作,隨時會導(dǎo)致數(shù)據(jù)庫服務(wù)器癱瘓,無法繼續(xù)提供服務(wù)。
而引入消息隊列則可以減少突發(fā)流量對應(yīng)用系統(tǒng)的沖擊。消費隊列就像“水庫”一樣,攔截上游的洪水,削減進(jìn)入下游河道的洪峰流量,從而達(dá)到減免洪水災(zāi)害的目的。
在這方面最常見的例子就是秒殺系統(tǒng),一般秒殺活動瞬間流量很高,如果流量全部涌向秒殺系統(tǒng),會壓垮秒殺系統(tǒng),通過引入消息隊列,可以有效緩沖突發(fā)流量,達(dá)到“削峰”的作用。
我們使用秒殺的場景來描述流量削峰,先看下面一張流程圖:
在上面的流程中,我們把秒殺服務(wù)稱為上游服務(wù),訂單服務(wù)、庫存服務(wù)、余額服務(wù)統(tǒng)稱為下游服務(wù)。客戶端發(fā)起秒殺的請求,秒殺服務(wù)收到客戶端發(fā)送的請求以后,創(chuàng)建訂單,修改庫存,扣減余額,這是秒殺的基本業(yè)務(wù)場景。
假如下游服務(wù)只能同時處理1000個并發(fā)請求,上游服務(wù)可以處理10000個并發(fā)請求,而客戶端發(fā)起了10000個請求,超出了下游服務(wù)可以處理的并發(fā)量,所以會導(dǎo)致下游服務(wù)發(fā)生宕機。這時就可以加入消息隊列來解決宕機的問題。看下面加入消息隊列的流程圖:
我們在上面的流程圖中加入了消息隊列,描述服務(wù)接收到客戶端發(fā)送的10000個請求以后,把所有的請求都寫入到消息隊列中,然后下游服務(wù)去訂閱消息隊列里面的秒殺請求,然后在去執(zhí)行自己的業(yè)務(wù)邏輯操作。
我們舉個簡單的例子,上游服務(wù)還是能處理10000個并發(fā)請求,下游服務(wù)還是只能處理1000個并發(fā)請求,那么這時候我們在消息隊列里面會允許存1000個并發(fā)請求。上游的秒殺服務(wù)接收到10000個并發(fā)請求,而消息隊列里面只能存1000個請求,多余的請求就不會存入到消息隊列里面,直接返回給客戶端提示“系統(tǒng)繁忙,請稍后!”。這就是所謂的流量削峰場景。這是由下游服務(wù)可以處理的并發(fā)量決定的。由于下游服務(wù)只能處理1000個并發(fā)請求,所以消息隊列里面只能存1000個秒殺,多余的秒殺請求全部返回客戶端提示。這樣就保證了下游服務(wù)的正常響應(yīng),不會導(dǎo)致下游服務(wù)發(fā)生宕機,提高了系統(tǒng)的可用性。
2、日志場景
優(yōu)化日志傳輸
為了程序的健壯性,我們一般會在程序中添加各種記錄日志的功能,比如錯誤日志、操作日志等等,看下面一張流程圖:
上面的流程圖是同步記錄日志的流程。使用同步記錄日志的流程,會使得整個流程花費的時間增多,而且也會容易造成業(yè)務(wù)系統(tǒng)宕機(如果數(shù)據(jù)庫損壞了,向數(shù)據(jù)庫記錄日志的操作將會產(chǎn)生錯誤)。我們可以使用消息隊列的方式優(yōu)化日志的傳輸。看下面的流程圖:
加入了消息隊列以后,可以縮短系統(tǒng)花費的時間,而且也可以達(dá)到應(yīng)用系統(tǒng)解耦的功能。
3、及時通訊場景
聊天室
消息隊列最主要功能是收發(fā)消息,其內(nèi)部有高效的通訊機制,因此非常適合用于消息通訊。
我們可以基于消息隊列開發(fā)點對點的聊天系統(tǒng),也可以開發(fā)廣播系統(tǒng),用于將消息廣播給大量接收者。
原文鏈接:https://www.cnblogs.com/dotnet261010/p/13099201.html
相關(guān)推薦
- 2022-07-02 使用numpy.mean()?計算矩陣均值方式_python
- 2023-01-17 python中終止協(xié)程和異常處理方式_python
- 2022-08-15 詳解Redis分布式鎖的原理與實現(xiàn)_Redis
- 2022-08-21 Python?Map函數(shù)保姆級使用教程_python
- 2022-05-15 Python數(shù)據(jù)結(jié)構(gòu)與算法中的棧詳解_python
- 2023-04-01 Python實現(xiàn)處理apiDoc轉(zhuǎn)swagger的方法詳解_python
- 2023-01-01 Python交換字典鍵值對的四種方法實例_python
- 2022-02-25 Linux下安裝Hadoop集群詳細(xì)步驟_Linux
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支