好兄弟這麼厲害的RabbitMQ ,你咋能不知道了呢?

RabbitMQ作為一款能實現高性能存儲分發消息的分佈式中間件,具有異步通信、服務解耦、接口限流、消息分發和業務延遲處理等功能,在實際生產環境中具有很廣泛的應用,其特性可以概括為如圖1所示。


好兄弟這麼厲害的RabbitMQ ,你咋能不知道了呢?

圖1 RabbitMQ的作用

正是由於RabbitMQ擁有如此多的特性,才使得其在實際應用系統中具有一席之地,本節主要介紹一下RabbitMQ的典型應用場景。

1.異步通信和服務解耦

以“用戶註冊”為實際場景,傳統的企業級應用處理用戶註冊的流程,首先是用戶在界面上輸入用戶名、郵箱或手機號等信息,確認無誤後,單擊“註冊”按鈕提交相關信息。

前端會將這個信息提交到後端相關接口進行處理,後端在接收到這些信息後,會先對這些信息進行最基本的校驗,校驗成功後會將信息寫入數據庫相關數據表中,而為了用戶註冊的安全性,後端會調用郵件服務器提供的接口發送一封郵件驗證用戶的合法性,或者調用短信服務的發送短信驗證碼接口給用戶進行驗證,最後才將響應信息返回給前端用戶,並提示“註冊成功”,整個流程如圖2所示。


好兄弟這麼厲害的RabbitMQ ,你咋能不知道了呢?

圖2 傳統的企業級應用系統用戶註冊流程

從圖2的流程可以看出,用戶從單擊“註冊”按鈕,提交相關信息之後便需要經歷“漫長”的等待時間,整體的等待時間約等於“寫入數據庫”+“郵箱驗證”+“短信確認”的處理時間之和。在處理過程中如果發郵件和發短信業務邏輯出現異常,整個流程將會終止,很顯然這種處理方式對於當前互聯網用戶來說幾乎不能接受!

仔細分析用戶註冊的整個流程,不難發現其核心的業務邏輯在於“判斷用戶註冊信息的合法性並將信息寫入數據庫”,而“發送郵件”和“短信驗證”服務在某種程度上並不歸屬於“用戶註冊”的核心流程,因而可以將相應的服務從其中解耦出來,並採用消息中間件如RabbitMQ進行異步通信,如圖3所示。


好兄弟這麼厲害的RabbitMQ ,你咋能不知道了呢?

圖3 引入RabbitMQ消息中間件後用戶註冊的流程

可以看到RabbitMQ的引入,將“一條線走到底”的業務服務模塊進行了解耦,系統接口的整體響應時間也明顯降低了許多,即實現了“低延遲”。從用戶的角度上看,這將給用戶帶來很好的體驗效果。

2.接口限流和消息分發

以“商城用戶搶購商品”為例,商城為了吸引用戶流量,會不定期地舉辦線上商城熱門商品的搶購活動,當搶購活動開始之前,用戶猶如“守株待兔”一般會盯在屏幕前等待活動的開始,當活動開始之時,由於商品數量有限,所有的用戶幾乎會在同一時刻單擊“搶購”按鈕開始進行商品的搶購,整體流程如圖4所示。


好兄弟這麼厲害的RabbitMQ ,你咋能不知道了呢?

圖4 商城商品搶購活動傳統的處理流程

毫無疑問,在搶購活動開始的那一刻,將會產生巨大的用戶搶購流量,這些請求幾乎在同一時間到達後端系統接口。而在正常的情況下,後端系統接口在接收到前端發送過來的請求時,會執行如下流程:

首先會校驗用戶和商品等信息的合法性,當校驗通過之後,會判斷當前商品的庫存是否充足,如果充足,則代表當前用戶將能成功搶購到商品,最後將用戶搶購成功的相關數據記入數據庫,並異步通知用戶搶購成功,儘快進行付款等。

然而,通過仔細分析發現,後端系統接口在處理用戶搶購的整體業務流程“太長”,而在這整塊業務邏輯的處理過程中,存在著先取出庫存再進行判斷,最後再進行減1的更新操作,在高併發的情況下,這些業務操作會給系統帶來諸多的問題。比如,商品超賣、數據不一致、用戶等待時間長、系統接口掛掉等現象。因而這種單一的處理流程只適用於同一時刻前端請求量很少的情況,而對於類似商城搶購、商品秒殺等某一時刻產生高併發請求的情況則顯得力不從心。

消息中間件RabbitMQ的引入可以大大地改善系統的整體業務流程和性能,如圖5所示為引入RabbitMQ後系統的整體處理流程。


好兄弟這麼厲害的RabbitMQ ,你咋能不知道了呢?

圖5 商城商品搶購活動傳統的處理流程

由圖5可以看出,RabbitMQ的引入主要是從以下兩個方面來優化系統的整體處理流程:

1)接口限流:當前端產生高併發請求時,並不會像“無頭蒼蠅”一樣立即到達後端系統接口,而是像每天上班時的地鐵限流一樣,將這些請求按照先來後到的規則加入RabbitMQ的隊列,即在某種程度上實現“接口限流”。

2)消息異步分發:當商品庫存充足時,當前搶購的用戶將可以搶到該商品,之後會異步地通過發送短信、發送郵件等方式通知用戶搶購成功,並告知用戶儘快付款,即在某種程度上實現了“消息異步分發”。


3)業務延遲處理

RabbitMQ除了可以實現消息實時異步分發之外,在某些業務場景下,還能實現消息的延時和延遲處理。下面以“春運12306搶票”為例進行說明。春運搶票相信讀者都不陌生,當我們用12306搶票軟件搶到火車票時,12306官方會提醒用戶“請在30分鐘內付款”。正常情況下用戶會立即付款,然後輸入相應的支付密碼支付火車票的價格。扣款成功後,12306官方會發送郵件或者短信,通知用戶搶票和付款成功。

然而,實際卻存在著一些特殊情況,比如用戶搶到火車票後,由於各種原因而遲遲沒有付款,過了30分鐘後仍然沒有支付車票的價格,導致系統自動取消該筆訂單。類似這種“需要延遲一定的時間後再進行處理”的業務在實際生產環境中並不少見,傳統企業級應用對於這種業務的處理,是採用一個定時器定時去獲取沒有付款的訂單,並判斷用戶的下單時間距離當前的時間是否已經超過30分鐘,如果是,則表示用戶在30分鐘內仍然沒有付款,系統將自動使該筆訂單失效並回收該張車票,整個業務流程如圖6所示。


好兄弟這麼厲害的RabbitMQ ,你咋能不知道了呢?

圖6 搶票成功後30分鐘內未付款的傳統處理流程

春運搶票完全可以看作是一個大數據量、高併發請求的場景,在某一時刻車票開搶之後,正常情況下將陸續會有用戶搶到車票,但是距離車票付款成功是有一定的時間間隔的。

在這段時間內,如果定時器頻繁地從數據庫中獲取“未付款”狀態的訂單,其數據量之大將難以想象,而且如果大批量的用戶在30分鐘內遲遲不付款,那從數據庫中獲取的數據量將一直在增長,當達到一定程度時,將給數據庫服務器和應用服務器帶來巨大的壓力,更有甚者將直接壓垮服務器,導致搶票等業務全線崩潰,帶來的直接後果將不堪設想!

早期的很多搶票軟件每當趕上春運高峰期時,經常會出現“網站崩潰”“單擊購買車票後卻一直沒響應”等狀況,某種程度上是因為在某一時刻產生的高併發,或者定時頻繁拉取數據庫得到的數據量過大等狀況,導致內存、CPU、網絡和數據庫服務等負載過高所引起的。

而消息中間件RabbitMQ的引入,不管是從業務層面還是應用的性能層面,都大大得到了改善,如圖7為引入RabbitMQ消息中間件後“搶票成功後30分鐘內未付款的處理流程”的優化。


好兄弟這麼厲害的RabbitMQ ,你咋能不知道了呢?

圖7 搶票成功後30分鐘內未付款的優化處理流程

從優化流程中可以看出,RabbitMQ的引入主要是替代了傳統處理流程的“定時器處理邏輯”,取而代之的是採用RabbitMQ的延遲隊列進行處理。延遲隊列,顧名思義指的是可以延遲一定的時間再處理相應的業務邏輯。

RabbitMQ的這一特性在某些場景下確實能起到很好的作用,比如上面講的“成功搶到票後30分鐘內未付款的處理流程”就是比較典型的一種。除此之外,商城購物時“單擊去付款而遲遲沒有在規定的時間內支付”的流程的處理、點外賣時“下單成功後遲遲沒有在規定的時間內付款”的流程的處理等都是實際生產環境中比較典型的場景。

除了上述所羅列的應用場景外,RabbitMQ在其他業務場景下也同樣具有廣泛的應用,在這裡就不再一一列舉了!


分享到:


相關文章: