當前位置:
首頁 > 知識 > MQ 消息中間件的使用和重構系統之間的耦合

MQ 消息中間件的使用和重構系統之間的耦合

1. 寫在前面

本文咱們來聊聊如何通過 MQ 消息中間件的使用,重構系統之間的耦合,讓系統具備高度的可擴展性。

首先看一張系統之間的耦合圖,大家先不用關注圖中數據查詢平台和實時計算平台的具體細節。

只需知道這裡的數據查詢平台和實時計算平台兩個系統,通過一套共享存儲(資料庫集群 緩存集群)進行了耦合。

2. 劃分系統邊界

只要有耦合,一旦要解決耦合,那麼第一個要乾的事就是先劃分清楚系統之間的邊界。

比如上面那兩套系統都共享了一套存儲集群,大家先思考一下,兩個系統之間的邊界應該如何劃分?

換句話說,中間那套緩存集群和資料庫集群,應該屬於哪個系統?要回答這個問題,主要就是考慮緩存集群和資料庫集群主要是給誰用的?

答案顯而易見,當然是給數據查詢平台用的。

說白了,緩存集群和資料庫集群都是數據查詢平台賴以生存的核心底層數據存儲,它們存儲的數據也都是屬於數據查詢平台的核心數據。

對於實時計算平台來說,他只不過是將自己計算後的結果寫入到緩存集群和資料庫集群罷了。

實時計算平台只要寫入過後,後續就不會再管那些數據了,所以這兩套集群明顯是不屬於實時計算平台的。

系統間的邊界劃分清楚之後,從整體架構來看,兩套系統間的關係應該是下面這樣:

3. 引入消息中間件解耦

現在我們劃分清楚了系統之間的邊界,接著下一步,就是引入消息中間件來進行解耦。

如果對消息中間件的使用場景還不太熟悉的朋友,可以先看看之前的文章:《哥們,你們的架構中為什麼要引入消息中間件?》,裡面對消息中間件的各種使用場景都有詳細闡述。

現在我們只要引入一個消息中間件,然後讓實時計算平台將計算好的數據按照預設的格式直接寫入到消息中間件即可。

同時在數據查詢平台這邊增加一個數據接入服務,負責將消息中間件里的數據消費出來,然後落地寫入到本地的緩存集群和資料庫集群。

整個過程如下圖所示:

通過上圖可以清晰的看到,兩個系統之間已經不再直接基於共享數據存儲進行耦合了,中間加入了MQ消息中間件,它僅僅是用於兩個系統之間的數據交互和傳輸,職責簡單,清晰明了。

這樣做最大的好處:數據查詢平台可以對湧入自身平台的數據,按照自己的需求進行定製化的管控,不會像之前那樣的被動。

因為湧入數據查詢平台的所有數據,都需要經過數據接入服務那一關,在數據接入服務那裡就可以隨意根據自己的情況進行管理。

4. 利用消息中間件削峰填谷

好,我們繼續,現在把目光集中到兩個系統上,進行痛點分析。

兩個系統間第一大痛點:實時計算平台會高並發寫入數據查詢平台,之前不做任何管控的時候,導致各種意外發生。

比如快速增長的寫庫壓力導致數據查詢平台必須優先cover住分庫分表那塊的架構,打破自己的架構演進節奏。

比如突然意外出現的熱數據因為不做任何寫入管控,一下子可能把資料庫伺服器擊垮。

因此一旦用消息中間件在中間擋了一層之後,就可以進行削峰填谷了。那什麼叫削峰填谷呢?

很簡單,如果不做任何管控,實時計算平台並發寫入資料庫集群,在高峰期會有一個陡然上升的尖峰。

打個比方:平時每秒寫入並發就500,但是高峰期寫入並發請求有5000,那麼就會突然冒出來一個尖峰,此時數據查詢平台的資料庫集群可能就會受不了。

那如果我們在數據接入服務里做一個限流控制,效果會怎麼樣呢?

也就是說,在數據接入服務里,根據當前數據查詢平台的資料庫集群能承載的並發上限進行控制。

比如最多承載每秒3000,那麼數據接入服務自己就控制好,每秒最多就往自己本地的資料庫集群里寫入每秒3000的請求,此時就會出現削峰填谷的效果。

雖然說在實時計算那邊,高峰期瞬時寫入壓力最大有5000/s,但是數據接入服務做了流量控制,最多就往本地資料庫集群寫入3000/s。

然後每秒就會有2000條數據在消息中間件里做一個積壓,但是積壓一會兒不要緊,最起碼保證在高峰期,我們把這個向上的尖峰給削平,這就是削峰。

高峰期過了之後,現在可能就100/s的寫入壓力,但是此時數據接入服務會持續不斷的從消息中間件里取出來數據,然後持續以最大3000/s的寫入壓力往本地資料庫集群里寫入。

那麼在低峰期,我們可以看到還會持續一段時間是3000/s的寫入速度往本地資料庫里寫,原來的低峰期是谷底,現在谷底被填平了,這就是所謂的填谷。

通過這套削峰填谷的機制,可以保證數據查詢平台以自己能接受的速率,均勻的把MQ里的數據拿出來寫入自己本地資料庫集群中。

這樣無論實時計算平台多高的並發請求壓力過來,哪怕是那種異常的熱數據,瞬間上萬並發請求過來也無所謂了。因為MQ中間件可以抗住瞬間高並發寫入,數據查詢平台永遠都是穩定勻速的寫入自己本地資料庫。

這樣一來,數據查詢平台就不需要去過多的care實時計算平台帶給自己的壓力了,可以按照自己的節奏進行各種架構迭代。

此時的架構圖如下所示,在數據接入服務中多了一個限流的模塊。

5. 手動流量開關配合資料庫運維

通過消息中間件將兩個系統隔離的另一大好處:數據查詢平台做任何數據運維的操作,比如DDL、分庫分表擴容、數據遷移,等等,已經跟實時計算平台徹底無關了。實時計算平台主要簡單的往消息中間件寫入,其他的就不用管了。

現在數據查詢平台如果要做一些資料庫運維的操作,就可以通過在數據接入服務中加入一個手動流量開關,臨時將流量開關關閉一會兒。比如選擇午睡這種相對低峰的時期,半小時內關閉流量開關。

然後此時數據接入服務就不會繼續往本地資料庫寫入數據了,此時寫入操作就會停止,半小時內迅速完成資料庫運維操作。等相關操作完成之後,再次打開流量開關,繼續從MQ里消費數據寫入到本地資料庫內即可。

這樣就完全避免了同時寫入數據,還同時進行資料庫運維操作的窘境。否則在耦合的狀態下,每次進行資料庫運維操作,還得實時計算平台團隊的同學配合一起進行各種複雜操作,才能避免線上出現故障。

現在完全不需要人家的參與了,自己團隊就可以搞定。

加入流量開關後,架構圖又變成了下面這樣:

6. 支持多系統同時訂閱數據

引入了消息中間件的第三大好處:其他一些系統也可以按需去MQ里訂閱實時計算平台計算好的數據。

舉個例子,這套平台里有數據質量監控系統,需要獲取計算數據進行數據結果準確性和質量的監控。

另外這套平台里還有數據鏈路監控系統,需要將MQ里的數據作為數據計算鏈路中的一個核心點數據採集過來,進行數據全鏈路的監控和自動追蹤。

如果沒有引入MQ消息中間件,那是不是會導致實時計算平台除了將數據寫入一份到資料庫集群,還需要通過介面發送給數據質量監控系統以及數據鏈路監控系統?

這樣簡直坑爹到不行,N個系統全部耦合在一起。

但是有了消息中間件,完全可以通過MQ支持的「Pub/Sub」消息訂閱模型,不同的系統都可以訂閱同一份數據,大家按需消費,按需處理,各個系統之間完全解耦。

這樣一來,整個系統可擴展性瞬間提升了很多,因為各個系統各自迭代和演進,都不需要強依賴其他的系統了。

最後我們來看看,兩個系統解耦後的架構圖:

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 千鋒JAVA開發學院 的精彩文章:

JVM中的對象內存布局?
過來人說:職業程序員不會這麼做!

TAG:千鋒JAVA開發學院 |