消息隊列(一):消息隊列應用場景

一、什麼是隊列

隊列(Queue)是一種常見的數據結構,其最大的特點就是先進先出(First In First Out),作爲最基礎的數據結構,隊列應用很廣泛。比如火車站排隊買票等等。可以用下圖表示隊列:

其中a1、a2、an表示隊列中的數據。數據從隊尾入隊列,然後從隊頭出隊列。

二、什麼是消息隊列

消息隊列(Message Queue)是一種使用隊列(Queue)作爲底層存儲數據結構,可以用於解決不同進程與應用程序之間通訊的分佈式消息容器,也可以稱爲消息中間件。

目前比較常用的消息隊列有ActiveMQ、RabbitMQ、Kafka、RocketMQ、Redis等。

消息隊列和隊列有什麼區別呢?

唯一的區別在於入隊列的時候稱爲生產者,出隊列的時候稱爲消費者。

三、消息隊列應用場景

消息隊列應用場景非常廣泛,下面我們列舉比較常見的幾個場景

1、分佈式場景

1.1、異步處理

一般我們寫的程序都是按照順序執行的(即同步的方式)。比如電商系統中訂單的例子,其執行順序如下:

  1. 用戶提交訂單。
  2. 訂單完成以後增加積分。
  3. 發生積分變動的短信通知。

可以用下面的流程圖表示:

如果按照上面的順序執行,假如每個服務都需要花費一秒,那麼客戶端就要花費3秒的時間。對於用戶來說,3秒的時間顯然是不能忍受的,那麼我們該如何解決呢?我們可以使用異步的方式來解決這個問題,看下面一張流程圖:

 按照這種方式,積分服務和短信服務使用線程異步的方式進行操作,那麼客戶端只需要花費1秒的時間就可以完成了。但是,這種異步的方式會帶來另外的問題:併發量降低。因爲積分服務和短信服務都需要在訂單服務裏面開啓線程,開啓的線程多了,會導致客戶端訪問訂單服務的併發量降低,可能導致客戶端提交訂單的實際時間會超過1秒鐘。那麼如何解決異步帶來的問題呢?那就是使用消息隊列,看下面的流程圖:

在上面的流程中,我們增加了一個消息隊列的角色,首先由客戶端提交訂單,然後把訂單寫入到消息隊列,積分服務和短信服務同時去消費消息隊列裏面的消息,這種方式不需要訂單服務在額外的開啓異步線程,客戶端可以實現真正的耗時1秒。

1.2、應用解耦

 我們還是以電商系統爲例進行講解,先看下面的流程圖:

上圖的業務邏輯:客戶端發起一個創建訂單的請求,創建訂單的時候,我們要先獲取庫存,然後在去扣減庫存,這樣訂單系統和庫存系統就形成了非常緊密的依賴關係。假如這時候庫存系統發生了宕機,由於訂單系統依賴於庫存系統,這時候訂單系統將不能使用。那麼如何解決呢?

看下面使用消息隊列的流程圖:

在上面的流程中,我們加入了消息隊列。首先客戶端發起創建訂單的請求,訂單的消息寫入到消息隊列裏面,然後庫存系統去消息隊列裏面訂閱消息,最後異步的去更新庫存系統。如果庫存系統發生了宕機,由於訂單系統不直接依賴於庫存系統,所以訂單系統可以正常的響應客戶端的請求。這樣就實現了應用解耦。

1.3、流量削峯

對於高併發的系統來說,在訪問高峯時,突發的流量就像洪水般湧向應用系統,尤其是一些高併發寫操作,隨時會導致數據庫服務器癱瘓,無法繼續提供服務。

而引入消息隊列則可以減少突發流量對應用系統的衝擊。消費隊列就像“水庫”一樣,攔截上游的洪水,削減進入下游河道的洪峯流量,從而達到減免洪水災害的目的。

在這方面最常見的例子就是秒殺系統,一般秒殺活動瞬間流量很高,如果流量全部湧向秒殺系統,會壓垮秒殺系統,通過引入消息隊列,可以有效緩衝突發流量,達到“削峯”的作用。

我們使用秒殺的場景來描述流量削峯,先看下面一張流程圖:

在上面的流程中,我們把秒殺服務稱爲上游服務,訂單服務、庫存服務、餘額服務統稱爲下游服務。客戶端發起秒殺的請求,秒殺服務收到客戶端發送的請求以後,創建訂單,修改庫存,扣減餘額,這是秒殺的基本業務場景。

假如下游服務只能同時處理1000個併發請求,上游服務可以處理10000個併發請求,而客戶端發起了10000個請求,超出了下游服務可以處理的併發量,所以會導致下游服務發生宕機。這時就可以加入消息隊列來解決宕機的問題。看下面加入消息隊列的流程圖:

我們在上面的流程圖中加入了消息隊列,描述服務接收到客戶端發送的10000個請求以後,把所有的請求都寫入到消息隊列中,然後下游服務去訂閱消息隊列裏面的秒殺請求,然後在去執行自己的業務邏輯操作。

我們舉個簡單的例子,上游服務還是能處理10000個併發請求,下游服務還是隻能處理1000個併發請求,那麼這時候我們在消息隊列裏面會允許存1000個併發請求。上游的秒殺服務接收到10000個併發請求,而消息隊列裏面只能存1000個請求,多餘的請求就不會存入到消息隊列裏面,直接返回給客戶端提示“系統繁忙,請稍後!”。這就是所謂的流量削峯場景。這是由下游服務可以處理的併發量決定的。由於下游服務只能處理1000個併發請求,所以消息隊列裏面只能存1000個秒殺,多餘的秒殺請求全部返回客戶端提示。這樣就保證了下游服務的正常響應,不會導致下游服務發生宕機,提高了系統的可用性。

2、日誌場景

2.1、優化日誌傳輸

爲了程序的健壯性,我們一般會在程序中添加各種記錄日誌的功能,比如錯誤日誌、操作日誌等等,看下面一張流程圖:

上面的流程圖是同步記錄日誌的流程。使用同步記錄日誌的流程,會使得整個流程花費的時間增多,而且也會容易造成業務系統宕機(如果數據庫損壞了,向數據庫記錄日誌的操作將會產生錯誤)。我們可以使用消息隊列的方式優化日誌的傳輸。看下面的流程圖:

加入了消息隊列以後,可以縮短系統花費的時間,而且也可以達到應用系統解耦的功能。

3、及時通訊場景

3.1、聊天室

 消息隊列最主要功能是收發消息,其內部有高效的通訊機制,因此非常適合用於消息通訊。

我們可以基於消息隊列開發點對點的聊天系統,也可以開發廣播系統,用於將消息廣播給大量接收者。

其他:

https://www.cnblogs.com/shihuibei/p/9633417.html

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