【本人禿頂程式設計師】阿里P7講解BAT必考面試題之訊息佇列!
←←←←←←←←←←←← 快!點關注
在面試大型網際網路公司的時候,很可能會被問到訊息佇列的問題:
- 在何種場景下使用了訊息中介軟體?
- 為什麼要在系統裡引入訊息中介軟體?
- 如何實現冪等?
鏈式呼叫是我們在寫程式時候的一般流程,為了完成一個整體功能,會將其拆分成多個函式(或子模組),比如模組A呼叫模組B,模組B呼叫模組C,模組C呼叫模組D。但在大型分散式應用中,系統間的RPC互動繁雜,一個功能背後要呼叫上百個介面並非不可能,這種架構有如下 幾個劣勢 :
1、 這些 介面之間耦合比較嚴重 ,每新增一個下游功能,都要對上有的相關介面進行改造;舉個例子:假如系統A要傳送資料給系統B和C,傳送給每個系統的資料可能有差異,因此係統A對要傳送給每個系統的資料進行了組裝,然後逐一發送;當代碼上線後,新增了一個需求:把資料也傳送給D。此時就需要修改A系統,讓他感知到D的存在,同時把資料處理好給D。在這個過程中你會看到,每接入一個下游系統,都要對A系統進行程式碼改造,開發聯調的效率很低。其整體架構如下圖:

2、 面對大流量併發時,容易被沖垮 。每個介面模組的吞吐能力是有限的,這個上限能力如果堤壩,當大流量(洪水)來臨時,容易被沖垮。
3、 存在效能問題 。RPC介面基本上是同步呼叫,整體的服務效能遵循“木桶理論”,即鏈路中最慢的那個介面。比如A呼叫B/C/D都是50ms,但此時B又呼叫了B1,花費2000ms,那麼直接就拖累了整個服務效能。

根據上述的幾個問題,在設計系統時可以明確要達到的目標:
1、 要做到系統解耦 ,當新的模組接進來時,可以做到程式碼改動最小;
2、 設定流量緩衝池 ,可以讓後端系統按照自身吞吐能力進行消費,不被沖垮;
3、 強弱依賴梳理,將非關鍵呼叫鏈路的操作非同步化,提升整體系統的吞吐能力 ,比如上圖中A、B、C、D是讓使用者發起付款,然後返回付款成功提示的幾個關鍵流程,而B1是通知付款後通知商家發貨的模組,那麼實質上使用者對B1完成的時間容忍度比較大(比如幾秒之後),可以將其非同步化。
在現在的系統視線中,MQ訊息佇列是普遍使用的,可以完美的解決這些問題的利器。下圖是使用了MQ的簡單架構圖,可以看到MQ在最前端對流量進行蓄洪,下游的系統ABC只與MQ打交道,通過事先定義好的訊息格式來解析。

引入MQ之後的系統架構、互動方式與最初的鏈式呼叫架構非常不同,雖然可以解決上文提到的問題,但也要充分理解其原理特性來避免其帶來的副作用,這裡以訊息佇列如何保證“訊息的可靠投遞”為切入點,來看看MQ的實現方式。
1. Client如何將訊息可靠投遞到MQ
1.Client傳送訊息給MQ
2.MQ將訊息持久化後,傳送Ack訊息給Client, 此處有可能因為網路問題導致Ack訊息無法傳送到Client,那麼Client在等待超時後,會重傳訊息 ;
3.Client收到Ack訊息後,認為訊息已經投遞成功。
2. MQ如何將訊息可靠投遞到Client
1.MQ將訊息push給Client(或Client來pull訊息)
2.Client得到訊息並做完業務邏輯
3.Client傳送Ack訊息給MQ,通知MQ刪除該訊息,此處有可能因為網路問題導致Ack失敗,那麼Client會重複訊息,這裡就引出消費冪等的問題;
4.MQ將已消費的訊息刪除
寫在最後:
如需Java架構資料,點關注,發簡信給我即可,先到先得!
禿頂程式設計師的不易,看到這裡,點了關注吧!
點關注,不迷路,持續更新!!!