2020年處於移動網際網路的下半場,各種技術層出不窮,雖然資料也在爆發式增長,但是高併發、高吞吐已經不再是首要的痛點,穩定、可靠才是王道。
本文作為一篇訊息佇列入門級介紹,幫助大家對訊息佇列有一個大致的了解,並對對時下流行的訊息佇列元件進行了簡單的比較,供大家做技術選型的參考。
1 什麼是訊息佇列
訊息佇列(Message Queue),從廣義上講是一種訊息佇列服務中介軟體,提供一套完整的資訊生產、傳遞、消費的軟體系統。
訊息佇列所涵蓋的功能遠不止於佇列(Queue),其本質是兩個程序傳遞資訊的一種方法。兩個程序可以分佈在同一臺機器上,亦可以分佈在不同的機器上。
眾所周知,程序通訊可以通過RPC(Remote Procedure Call,遠端過程呼叫)進行,那麼我們為什麼要用訊息佇列這種軟體服務來傳遞訊息呢?
下面我們以春節訂火車票為例進行說明,流程如下。
拿到年終獎了,準備買車票帶著媳婦兒回家過年。你開啟12306手機App開始做如下操作:
第一步:輸入車票資訊,傳送訂票請求。
起點站:北京。
終點站:成都。
出發時間:臘月29晚上8點。
票數:2張。
座席:硬臥。
第三步:3s後,應用告訴你訂票失敗。
第四步:你修改車次,重新發送訂票請求。應用重複第二步繼續等待。又一個3s後,12306 App告訴你訂票成功。
12306 App在處理上圖邏輯時,會遇到以下挑戰:
(1)今天這個車次只售出4000張票,而實際有30萬人傳送了訂票資訊,如果逐一請求處理,那麼90%以上的人都將要耗時3s來等待,怎麼辦?
(2)下游有20個系統需要在訂票成功後進行通知,如果逐一呼叫這些系統的介面進行通知,而其中一個通知任務執行失敗,那麼已經通知成功的任務會怎樣?
(3)12306 App架構會不斷調整,當資料結構發生變化時,下游20個系統都隨著一起變化嗎?
以上只是隨機列舉了一些常見的問題,如何才能優雅地處理呢?
答案是:訊息佇列!
2 為什麼需要訊息佇列
我們平時什麼時候可能會用到訊息佇列呢?下面結合剛才的流程圖來介紹訊息佇列的適用場景。
▊ 削峰填谷
業務系統在超高併發場景中,由於後端服務來不及同步處理過多、過快的請求,可能導致請求堵塞,嚴重時可能由於高負荷拖垮Web伺服器。
我們都希望流量如上圖虛線部分一樣一直比較平穩,這樣我們的系統也會更加穩定。但是實際的流量會隨著時間不短變化,像12306 App這樣的App流量大得難以想象,而一年中不同的時間段,其流量也不同。為了能支援最高峰流量,我們通常採取短平快的方式——直接擴容伺服器,增加服務端的吞吐量。
優點是顯而易見的,短時間內吞吐量增加了好幾倍,甚至數十倍。缺點也明顯,流量低峰期伺服器相對較閒。
如何平衡平時的空閒與節假日的超高峰呢?我們想到了訊息佇列(比如Apache RocketMQ,Apache Kafka),也是目前業界比較常用的手段。利用訊息佇列扭轉處理訂票請求,告知使用者30min內會告訴他/她訂票結果。優缺點明顯:效能提升了,但是我們作為業務開發人員,還要維護一個訊息佇列服務,人手完全不夠。訊息中介軟體呼之欲出。
▊ 程式間解耦
不同的業務端在聯合開發功能時,常常由於排期不同、人員調配不方便等原因導致專案延期。其實,其根本原因是業務耦合過度。
下圖中,上下游系統之間的通訊是彼此依賴的,所以不得不協調上下游所有的資源同步進行,跨團隊處理問題顯然比在團隊內部處理問題難度大。
你是否依稀記得另一個團隊的同事呼叫你的API,你告訴他發個請求過來,你打斷點一步一步除錯程式碼的場景?
你是否記得為了協調開發資源、QA資源,以及協調上線時間等所做的一切,你被老闆罵了多少次,最後還是延期了:我們依賴他們,他們的QA說,高峰期不讓釋出。
加入訊息佇列後,不同的業務端又會是何種情況呢?
上下游系統進行開發、聯調、上線,彼此完全不依賴,也就是說,系統間解耦了。
▊ 非同步處理
處理訂票請求是一個漫長的過程,需要檢查預訂的車次是否有預訂數量的票、下單扣庫存、更新快取等一系列操作。這些耗時的操作,我們可以通過使用訊息佇列的方式,把提交請求成功的訊息告訴使用者。然後非同步處理這些耗時的操作,保證30min內能把處理的結果通過簡訊推送給使用者,否則系統處理多久,使用者就會等多久。
▊ 資料的最終一致性
我們舉例說明。很懷念每月的1號,可以向老婆的“財務部”繳費了。你的工資在招商銀行,你老婆的工資在北京銀行。通常,兩個系統的通訊過程如下。
如果通訊失敗,怎麼保證你的錢“上交”了呢?業內常用的手段就是訊息佇列。訊息系統的優點:
(1)免去了招商銀行App多次重試(發起請求)的複雜邏輯。
(2)免去了北京銀行App處理過多重試請求的壓力。
(3)即使北京銀行服務不可用,業務也不受影響。
3 常見訊息佇列
這裡對時下流行的訊息佇列元件進行了簡單的比較,供大家做技術選型的參考。
Apache RocketMQ是一款開源的、分散式的訊息投遞與流資料平臺。出生自阿里巴巴,經歷了近十年雙11核心交易鏈路打磨,可以支撐萬億級訊息洪峰。
作為Apache頂級開源專案之一,其在GitHub上有10000+ star、5000+ fork、170+ contributors(在GitHub上提交程式碼並被採納的開發者),目前中國網際網路、金融等行業Top級企業75%以上都在使用,已經成為雲原生時代企業上雲的核心基礎設施!
學習掌握Apache RocketMQ,博文菌強烈推薦《RocketMQ分散式訊息中介軟體:核心原理與最佳實踐》一書。
李偉 著
作者有多年分散式系統的實戰經驗,特別是在訊息佇列方面經驗豐富。本書根據作者在專案中使用RocketMQ的實際經驗,結合實際原始碼,由淺入深地講解了RocketMQ核心功能的具體實現邏輯,並從訊息佇列的應用場景出發,使讀者快速地了解MQ解決的問題域。
通過閱讀本書,不僅可以了解如何在專案中使用訊息佇列,還能學習到RocketMQ的實現細節,進一步提升對RocketMQ系統本身的把控力度。