如何優雅的使用MQ-詳述功能場景

消息隊列(MQ)是一種不同應用程序之間(跨進程)的通信方法。應用程序通過寫入和檢索出入列隊的數據(消息)來通信,而無需通過專用連接來鏈接它們。消息傳遞指的是程序之間通過在消息中發送數據進行通信,而不是通過直接調用彼此來通信,直接調用通常是用於諸如遠程過程調用(Remote Procedure Call. RPC)的技術。排隊指的是應用程序通過隊列來通信。隊列的使用除去了接收和發送應用程序同時執行的要求。這樣天然的就實現了異步的目標。那麼MQ還有哪些功能場景呢。下面逐一介紹。

解耦

如何優雅的使用MQ-詳述功能場景

MQ最直接的使用場景就是可以將兩個系統進行解耦,比如我們的貨款抵扣業務場景,用戶生成訂單發送MQ後立即返回,結算系統去消費該MQ進行用戶賬戶金額的扣款。這樣訂單系統只需要關注把訂單創建成功,最大可能的提高訂單量,並且生成訂單後立即返回用戶。而結算系統重點關心的是賬戶金額的扣減,保證賬戶金額最終一致。這個場景裡面還會涉及到重試冪等性問題,後面有介紹。

削峰填谷

還是以訂單系統和結算系統場景為例,如果訂單系統通過RPC框架來調用結算系統,在有高峰促銷的情況下生成訂單的量會非常大,而且由於生成訂單的速度也非常快,這樣勢必會給結算系統造成系統壓力,服務器利用率則會偏高,但在不是高峰的時間點訂單量比較小,結算系統的服務器利用率則會偏低。對於結算系統來說就會出現下面這樣的高峰波谷現象圖。

如何優雅的使用MQ-詳述功能場景

那麼如果通過MQ的方式,將訂單存儲到MQ隊列中,消費端通過拉取的方式,並且拉去速度有消費端來控制,則就可以控制流量趨於平穩。這樣對於結算系統來講,就達到了削峰填谷的目的。或者說起到了流控的目標。接下來,我們介紹一下拉取方式。

拉取模式指用戶在代碼裡主動調用pull方法,不需要在配置文件裡面再配置,拉取的速度由用戶控制,調用一次拉取一次消息進行消費,這裡要重視消費的速度如果消費性能下降一定會造成積壓,因此用戶自己啟用多線程控制並行度以提高消費速度。

代碼樣例:

如何優雅的使用MQ-詳述功能場景

method: pull(String topic,MessageListener listener)

topic:指消費的主題名

listener:是一個回調對象,當pull拉取到消息後會主動調用listener.onMessage(),

與監聽模式的區別是:監聽模式由MQ客戶端守護線程去不停的拉取消息進行消費,拉取模式由用戶控制拉取的頻率,不主動調用就不會消費消息。但是都不需要主動對消息進行確認。這種方式更適合寫場景,保證最終結果落地即可,因為讀是需要立即返回以免讓用戶長時間等待從而影響用戶體驗。

最終一致性

如何優雅的使用MQ-詳述功能場景

一致性問題分為強一致性、弱一致性、最終一致性。大多數互聯網業務要求實現最終一致性。還是以訂單系統和結算系統業務場景舉例,訂單系統創建成功一個訂單後給用戶返回的結果即是成功並明確告訴用戶會從賬戶中扣除相應的金額。那麼結算系統需要保持跟訂單系統相同的狀態即從用賬戶中實際扣除一致的金額。訂單系統會涉及兩個動作,一個是創建成功訂單,一個是發送成功通知到MQ,我們就可以把這兩個動作放入到一個本地事務中,要麼成功要麼失敗。當一次發送MQ失敗之後,可以結合定時任務進行補償,這樣可以保證生成訂單的結果可以落地到mq的存儲中。同樣結算系統消費端依靠MQ重試機制一直髮送消息,直到消費端最終確認扣款業務成功處理完成。這樣我們通過消息落地加補償,消費端從業務上面考慮重複消費的保障,也就是做好冪等性操作,利用MQ實現了最終一致性。

廣播消費

MQ有兩種消息模式一種是點對點模式,一種是發佈/訂閱模式(最常用的模式)。同時發佈/訂閱模式按照消費類型又可以分為集群消費和廣播消費。大部分情況下我們使用的是集群消費。

集群消費:MQ發送任何一條消息,集群中只有一臺服務器可隨機消費到這條消息。如下圖:

如何優雅的使用MQ-詳述功能場景

廣播消費:MQ發送每一條消息,集群中的每一臺服務器至少消費到一次。如下圖:

如何優雅的使用MQ-詳述功能場景

廣播消費舉例:消息推送系統。首先某一個客戶端與消息中心應用集群中的一臺服務器建立長連接並將連接session信息保存到當前服務器內存中,集群在消費業務消息的時候,是不知道該客戶端建立的長連接在哪一臺服務器上面。這個時候通過廣播消費,集群中的每一臺服務器都可以消費到業務消息。在決定向用戶推送通知之前會判斷當前服務器內存中是否有該客戶端的連接session信息,如果有則推送,進而客戶端通過http協議拉取用戶的消息實體。如果session信息不在當前服務器上面,則丟棄。如下圖:

如何優雅的使用MQ-詳述功能場景

廣播消費注意事項:

1、消費進度在消費端管理,比如默認會在主目錄下創建offset文件夾,偏移量文件存儲在offset目錄下,出現重複的概率要大於集群消費。

2、MQ可以確保每條消息至少被每臺消費方服務器消費一次,但是如果消費方消費失敗,不會進入重試,因此業務方需要關注消費失敗的情況。

3、由於廣播消費消息不會進行確認,所以管理端上顯示的積壓數會一直不變,需要以出對數為準。

使用集群消費模擬廣播

在發佈/訂閱模式中,如果是集群消費,那麼一條消息只能被集群中的隨機一臺服務器消費到,如果我們有需要集群中的每臺服務器消費到比如上面的消息推送的例子,我們使用廣播消費來實現。但是廣播消費有一些弊端比如不支持順序消息,消費進度在客戶端維護出現重複的幾率要大於集群模式,廣播模式下不能維護消費進度所以管理端上面的積壓數一直保持不變,我們就必須以出隊數為準,也就是不能夠支持消息堆積的查詢。如果要規避這些弊端,那麼我們可以利用集群消費來模擬廣播,在集群消費中,我們的每臺服務器上面的消費APPID是相同的,如果要達到廣播的效果,那麼每臺服務器上面的消費APPID保持不同就可以了。

如何優雅的使用MQ-詳述功能場景

重試之坑

如何優雅的使用MQ-詳述功能場景

MQ的重試功能可以保證數據結果最終得到處理,但同時也正因為有重試那麼在業務處理的時候就需要格外注意冪等性的問題。比如貨款抵扣業務,訂單系統生成訂單之後調用結算平臺去扣除用戶的賬戶金額。結算平臺要根據流水號去計算,如果訂單系統在調用結算平臺的時候發生了網絡異常,造成了結算平臺實際上已經得到請求並且已處理。訂單系統一側認為發生異常需要重試,後續再發送到結算平臺的訂單就會造成重複扣款問題。所以流水號尤其要注意需要保證重試過程中每次發送的流水號是一致的,結算平臺會根據流水號去做業務校驗,如果已經處理,則丟棄,最終確保冪等性。

總結

我們介紹了MQ常見的使用場景,以及每種場景下的使用注意事項。尤其是在重試功能中,重試本來是MQ提供的一種保持數據最終可以得到確認的方法,但是如果業務使用上面不注意冪等性,則會帶來業務數據的不一致甚至像重複扣款這樣比較嚴重的後果。我們還介紹了發佈/訂閱模式下的廣播消費的使用舉例,也介紹了它的缺點以及可以使用集群消費來模擬廣播。鑑於以上每種場景都給我們提供了很好的說明使得大家在以後使用MQ的過程中可以更好的發揮MQ的強大作用。

學習方法:

當你真正開始學習的時候難免不知道從哪入手,導致效率低下影響繼續學習的信心。

但最重要的是不知道哪些技術需要重點掌握,學習時頻繁踩坑,最終浪費大量時間,所以有一套實用的視頻課程用來跟著學習是非常有必要的。

為了讓學習變得輕鬆、高效,今天給大家免費分享一套阿里架構師傳授的一套教學資源。幫助大家在成為架構師的道路上披荊斬棘。

這套視頻課程詳細講解了(Spring,MyBatis,Netty源碼分析,高併發、高性能、分佈式、微服務架構的原理,JVM性能優化、分佈式架構)等這些成為架構師必備的內容!

而且還把框架需要用到的各種程序進行了打包,根據基礎視頻可以讓你輕鬆搭建分佈式框架環境,像在企業生產環境一樣進行學習和實踐。

如何優雅的使用MQ-詳述功能場景

後臺私信回覆“架構” 就可以馬上免費獲得這些視頻資料!最後,做一個愛思考,懂思考,會思考的程序員。


分享到:


相關文章: