在面試大型網際網路公司的時候,很可能會被問到訊息佇列的問題:
1.在何種場景下使用了訊息中介軟體?
2.為什麼要在系統裡引入訊息中介軟體?
3.如何實現冪等?
鏈式呼叫是我們在寫程式時候的一般流程,為了完成一個整體功能,會將其拆分成多個函式(或子模組),比如模組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學習是不是有了更多的感悟~
金三銀四的跳槽季來襲,網易雲課堂為同學們準備了為期一週的Java進階面試季系列直播課。由多位擁有10+年Java開發經驗的講師向你傳道高併發、分散式、大資料、高可用系統的架構設計。
福利1 免費直播課程
《網易雲課堂Java進階面試季系列直播課》
適聽人群:Java初、中級開發工程師
3.4-3.10 連續7天每晚8點準時直播
▼
3月4日:面試季~搞懂Docker容器化技術,面試不掉鏈子
3月5日:面試季~為了高薪,請你一定要搞懂搜尋引擎核心原理
3月6日:面試季~面試加分項,教你搞定分散式事務
3月7日:面試季~學會分散式鎖,讓面試官對你另眼相看
3月8日:面試季~90分鐘搞定高併發快取相關的面試
3月9日:面試季~如何解答分散式架構中怎麼做系統監控?
3月10日:面試季~架構面試題 | 你對系統架構有什麼樣的理解?
福利2 Java開發資料包
想要獲得Java進階直播課與資料包
可以掃描下方二維碼,
新增網易雲課堂Java助教小姐姐
免費課程,名額有限,先到先得~~