1. 程式人生 > >系統架構中為什麼要引入訊息中介軟體?

系統架構中為什麼要引入訊息中介軟體?

“在本文的開頭,我們將討論訊息中介軟體的高頻訪問問題,它也將涵蓋MQ中介軟體的一些常見技術問題。如果面試官看了你的簡歷中使用MQ中介軟體的經歷,可能會有以下問題:在你的公司的生產環境中使用了什麼訊息中介軟體?為什麼要將訊息中介軟體引入系統?引入訊息中介軟體的優點和缺點是什麼?好,讓我們逐一分析。

一、你們公司生產環境用的是什麼訊息中介軟體?

首先,您可以說您的公司選擇了哪種訊息中介軟體,比如Rabbit MQ,然後可以對您選擇的不同MQ中介軟體技術進行一些初步分析。例如:ActiveMQ是一個老式的新聞中介軟體。在中國,許多公司曾經廣泛使用過它,並且擁有強大的功能。但問題在於,ActiveMQ不能支援Internet公司高併發性、高負載和高吞吐量的複雜場景,而且中國的Internet公司數量較少。此外,一些傳統企業使用ActiveMQ進行非同步呼叫和系統解耦。然後您可以說RabbitMQ,它具有支援高併發性、高吞吐量、高效能以及非常完美和方便的後臺管理介面的優點。此外,他還支援叢集、高可用性部署架構、高可靠訊息支援和更好的功能。

此外,經過調查,大型RabbitMQ叢集支援自身業務的案例更多,國內各種中小型網際網路公司使用RabbitMQ的做法也更多。此外,RabbitMQ的開放原始碼社群非常活躍,通過頻繁的迭代來修復發現的bug並對其進行優化,所以經過全面考慮,公司採用了RabbitMQ。但是RabbitMQ也有一些缺點,即它基於Erlang語言開發,因此更難分析內部原始碼,更難對原始碼進行深入定製和改造。畢竟,它需要更堅實的Erlang語言基礎。然後我們可以討論一下RocketMQ,它是Ali的開放原始碼。它已經通過了Ali生產環境中高併發性和高吞吐量的測試。它還支援特殊的場景,如分散式事務。基於Java語言開發了RoCKMQ。它適合於原始碼的深入閱讀。有必要在原始碼級別解決線上生產問題,包括二次開發和修改原始碼。另一個是卡夫卡。Kafka的訊息中介軟體特性明顯小於上面提到的MQ中介軟體的特性。但是Kafka的優點是它被設計用於超高吞吐量的實時日誌採集、實時資料同步、實時資料計算和其他場景。因此,卡夫卡被廣泛應用於具有實時計算技術的大資料領域(如火花流、風暴、Fl.)。但它很少用於傳統的MQ中介軟體使用場景。PS:如果您還沒有在自己的計算機上部署上述MQ技術,並且沒有編寫一些HelloWorld經驗,那麼建議您首先到每種技術的官方網站上查詢HelloWorld演示,並自己執行和播放。

二、為什麼在你們系統架構中要引入訊息中介軟體?

要回答這個問題,您應該首先討論訊息傳遞中介軟體的常見使用場景。
然後,根據您自己的系統的相應使用場景,我將討論通過將訊息中介軟體引入到您的系統中解決了哪些問題。

1)系統解耦

假設您有一個系統A,它產生核心資料,現在下游系統B和C需要該資料。

很簡單。系統A只調用系統B和系統C的介面直接向它們傳送資料。

整個過程,如下圖所示。

但如果我們談到系統D、系統E、系統F、系統G等等,那麼其他十幾個系統會慢慢需要這些核心資料嗎?如下圖所示。

別以為這是開玩笑。一個大型系統通常被劃分為幾十個甚至數百個子系統。每個子系統對應多個服務。這些系統和系統之間存在著複雜的關係。
如果系統產生核心資料,那麼無數其他下游系統可能需要它來實現各種業務邏輯。
此時,如果您採用上述模式來設計系統體系結構,那麼負責系統A的學生絕對會厭煩至死。
首先,有人來要求他向一個新系統H傳送資料。系統A的學生必須修改程式碼,然後在程式碼中新增呼叫新系統H的過程。
稍後,舊的系統B將離線,告訴系統A的學生:不要給我資料,然後系統A將再次修改程式碼,並停止給系統B。
那麼,如果下游系統突然出現故障怎麼辦?系統A的呼叫程式碼中是否引發異常?系統A的學生收到警報說系統不正常,他不得不去注意哪個下游系統出故障了。

因此,在實際的系統架構設計中,如果都採用這種系統耦合方式,在某些情況下是絕對不合適的,並且系統耦合程度太嚴重。

而耦合不是核心鏈路的呼喚,而是一些非核心場景(如資料消耗)導致系統耦合,這將嚴重影響上下游系統開發和維護的效率。

因此,在上述系統架構中,MQ中介軟體可以實現系統解耦。

系統A將其核心資料之一發送給MQ,MQ的下游系統希望自己使用它,並且不需要就取消對資料的消耗,如下圖所示。

2)非同步呼叫

假設您有一個系統呼叫連結,系統A呼叫系統B,通常需要20ms;系統B呼叫系統C,通常需要200ms;系統C呼叫系統D,通常需要2秒,如下圖所示。

現在最大的問題是使用者的請求來得很慢,因為完成一個連結需要20ms+200ms+2000ms(2s)=2220ms,或者超過2秒。
但實際上,系統A在鏈路呼叫系統B和系統B呼叫系統C,這兩個步驟加起來是220M。
由於引入了系統C呼叫系統D步驟,最終的鏈路執行時間超過2秒,這直接將鏈路呼叫效能降低了10倍,這是鏈路執行緩慢的罪魁禍首。
此時,我們可以考慮是否可以將系統D從連結中拉出來進行非同步呼叫。事實上,許多業務場景都允許非同步呼叫。
例如,當您訂購外賣時,單擊訂單並支付,賬戶扣除錢,建立訂單,並通知商家為您準備菜。
接下來,你需要騎車送餐嗎?然後,尋找騎手的過程需要一個複雜的演算法來實現排程,這非常耗時。
但事實上,在幾十秒後完成騎手的排程是可以的,因為當你付錢的時候,它並不真的需要找到一個好的騎手,也不是必須的。
因此,我們能否採取步驟找到一個騎手送餐給您脫離連結,並使其非同步,即使它被延遲了數十秒,但只要我們找到一個騎手送餐給您在一定的時間範圍?
這是否允許您更快地在外賣點下訂單?一旦付款成功,可以建立訂單,扣除帳戶,並通知商家立即為您準備菜餚。這個過程可能需要數百毫秒。
然後,後臺非同步可能需要幾十秒才能找到騎手通過排程演算法遞送餐點,但是這個步驟不會快速影響我們的訂購。
當然,我們不是說那些熟悉的外賣平臺的技術框架必須以這種方式實現,而是使用生活中的一個常見示例來說明它。

所以上面的連結是一樣的。如果業務流程支援非同步,我們能否考慮將系統C對系統D的呼叫撤出以進行非同步,而不是依次在連結中對呼叫進行同步?
以這種方式,實現的思想是系統A->系統B->系統C,它直接消耗220ms並獲得成功。
然後,系統C向MQ中介軟體傳送訊息,MQ中介軟體被系統D使用,並緩慢非同步以執行消耗2s的業務流程。這樣,核心鏈路的效能直接提高了10倍。

整個過程,如下圖所示。

3)流量削峰

假設你有一個系統,平時正常的時候每秒可能就幾百個請求,系統部署在8核16G的機器的上,正常處理都是ok的,每秒幾百請求是可以輕鬆抗住的。

但是如下圖所示,在高峰期一下子來了每秒鐘幾千請求,瞬時出現了流量高峰,此時你的選擇是要搞10臺機器,抗住每秒幾千請求的瞬時高峰嗎?

如果瞬時峰值每天只有半小時,那麼它直接減少到每秒數百個請求。如果線上部署許多機器,那麼每臺機器每秒可以處理幾十個請求。那不是浪費機器資源嗎?
大多數情況下,每秒數百個請求,一臺機器就足夠了,但是為了抵禦每天的瞬時峰值,部署了10臺機器,每天使用半小時,並且在其他時間浪費資源。

但是,如果部署一臺機器,它會導致一個瞬間的高峰時間,這會淹沒您的系統,因為絕對沒有辦法每秒承受數千個請求。
此時,我們可以使用MQ中介軟體來降低流量峰值。所有機器前面都裝有一層MQ。通常每秒可以容易地接收數百個請求。
一旦達到瞬時峰值,每秒可以備份數千個請求,然後機器緩慢地處理和消耗。
當高峰期結束並且消耗持續時間稍長時,將消耗MQ中的積壓資料。

這是MQ的典型應用,它使用有限的機器資源承載高併發請求。如果業務場景允許非同步調峰,則高峰期在MQ中積壓一些請求,然後高峰期結束,並且後端系統在一定時間段之後不再積壓,那麼使用這種技術方案是非常合適的。