訊息中介軟體該如何實現高可用架構?
1. 背景引入
這篇文章,我們來聊一下訊息中介軟體高可用架構的一些原理。
對於一個合格的高階 Java 工程師而言,你肯定會碰到在系統裡用到 MQ(訊息佇列)的場景。那麼這個時候你需要基於你的業務場景和需求,考慮在使用 MQ 的時候可能遇到的一些技術問題。
接著,你必須得針對這些技術問題設計一套完整的技術方案。
你需要從 訊息的訂閱模式 、 訊息的生產到消費全鏈路不丟資料 、 訊息中介軟體本身如何保證高可用 等各個角度切入,來考慮好你的系統和 MQ 對接之後的完整技術方案。
所以,本文就來聊聊訊息中介軟體高可用的架構原理。
2. 先來思考一下訊息中介軟體的可用性問題
咱們先拋開各種具體的技術,思考一下什麼是 MQ 的可用性問題?
大家看看下面的圖,其實道理很簡單。假設你的 MQ 就部署在一臺機器上,那麼正常情況下,生產者都會發送訊息到 MQ 去,然後讓消費者獲取到。
但是萬一天有不測風雲,MQ 部署的那臺機器因為一些莫名的原因 MQ 自己本身的程序掛掉了或者是那臺機器直接就宕機了,那麼這種時候該怎麼辦呢?
很尷尬,是不是?結果是很明顯的。生產者沒法傳送資料出去,然後消費者也沒法獲取到資料了。
然後整個系統不就完蛋了?因為系統的核心流程根本無法跑通了,對不對?
MQ 宕機就直接導致你的系統本身也故障了,然後可能會導致你的公司對外的 App、網站等產品就無法運作了,使用者無法使用你們公司的服務了。
如果你們公司是電商平臺、外賣平臺、社交平臺。那麼來這麼一出,不是會導致公司損失慘重?
如果你的系統持續幾個小時無法被人使用,本來你公司電商平臺一天營收可以達到 1 億,結果現在導致幾個小時內無法下單購買商品,最後當天營收就 5000 萬,那麼你的公司是不是直接活生生損失了 5000 萬?
這個真的不是開玩笑的,如果大家留意網際網路行業的新聞的話和小道訊息的話,就應該知道近幾年一些大型網際網路公司都出現過類似的情況,損失慘重。咱們做碼農的就得被祭天了,是不是?
3. 叢集化部署 + 資料多副本冗餘
好,問題來了!現在你感覺一個 MQ 中介軟體應該如何實現高可用呢?
這裡的方式有很多種,比如說 資料多副本冗餘 、 叢集映象同步機制 。我們就拋開具體的技術來從本質層面思考一下 MQ 叢集實現高可用的幾種方式。
先來看下面的一張圖,假設我們寫到 MQ 的資料都被多副本冗餘了,也就是你寫的每一條訊息都被複制到了其他的機器上去了。
那麼此時任何一臺機器宕機,似乎都不會影響我們跟 MQ 繼續通訊,而且寫出去的資料似乎也都還在。
上面的圖裡,MQ 採用叢集模式部署到了兩臺機器上去,然後生產者給其中一臺機器寫入一條訊息,該機器自動同步複製給另外一臺機器。
此時資料在兩臺機器上,就有兩個副本了。那麼如果第一臺機器宕機了,會影響我們嗎?
答案是: 不會 。
因為資料本身是多副本冗餘的,此時消費者完全可以從第二臺機器消費到這條訊息,並且生產者還可以繼續給第二臺機器寫入訊息,資料沒丟失。
而且,系統根本不用中斷流程,還可以繼續執行,我們看下面的圖。
這種感覺是不是很棒?實際上這種 MQ 叢集化部署架構以及資料多副本冗餘機制,是非常常見的一種高可用架構。
Kafka 這個極為優秀的訊息中介軟體,就是採用的這種架構保證高可用、資料容錯性。
4. 多副本同步複製強制要求
但是這裡你要思考另外幾個問題。
第一個問題,你在寫資料到其中一臺機器的時候,是不是有這樣的要求:必須得讓那臺機器複製資料到另外一臺機器了,保證叢集裡一定有這條資料雙副本了,才可以認為本次寫成功了?
沒錯,假如你要是不能保證這一點,比如你就寫資料給了其中一臺機器,然後它還沒來得及複製給另外一臺機器呢,直接第一臺機器就宕機了。
此時,雖然你可以繼續基於第二臺機器傳送訊息和消費訊息,但是你剛才傳送的一條訊息就丟失了。
大家看下面的圖來理解一下這個場景。
所以對於採用這種機制的時候,你必須得讓生產者通過一些引數的設定,保證寫一條訊息到某臺機器,必須同步這條訊息到另外一臺機器成功。等到叢集裡有雙副本了,然後才可以認為這條訊息寫成功了。
只要剛寫一臺機器他就宕機,還沒來得及複製到另外一臺機器的話,本次寫應該報錯失敗。然後,你應該重試再次寫入資料到 MQ 叢集裡去。
大家看看下面的圖。只要你一次寫成功了,就保證肯定已經同步資料為雙副本了。此時,哪怕一臺機器宕機,資料不會丟失,生產和消費都可以有條不紊地繼續進行。
5. 多機器承載多副本強制要求
第二個問題,假如說現在你的叢集中本來有兩臺機器,現在其中的一臺 宕機了 ,只有一臺機器了,你還能允許你的生產者對唯一的那臺機器繼續寫入資料嗎?
答案是: 否 。
因為,如果叢集裡只有一臺機器可以承載寫入,那麼萬一剩餘的一臺機器又宕機了呢?是不是還是會導致資料丟失,叢集完蛋?
所以說,你的生產者同理應該基於引數設定一下,叢集裡必須有超過兩臺機器可以接收你的資料副本複製。
否則如果只有一臺機器可以接受你的資料副本複製的話,那麼還是算了。
大家看看下面的圖,感受一下那個場景。
假設叢集裡有 3 臺機器,那麼其中一臺宕機了,你後續再寫入另外一臺的時候,判斷一下叢集裡還有剩餘兩臺機器,足以保證資料雙副本的高可用性和容錯性,所以可以繼續正常的寫入資料到 MQ 叢集裡去。
實際上,上面說的那一整套的機制,在 Kafka 裡都可以採用。它有對應的一些引數可以配置資料有幾個副本,包括你每次寫入必須複製到幾臺機器才可以算成功,否則就要重新發送。還可以通過引數設定,叢集剩餘機器必須可以承載幾個副本才能繼續寫入資料。
通過這一整套方案的設計和基於具體技術的落地,才可以保證在叢集化部署的情況下,叢集必須有幾臺機器承載多副本,同時資料寫入之後必須是保證多副本冗餘的。
此時,任何機器宕機,資料都不會丟失,還可以正常讓系統繼續執行。
6. 架構原理與技術無關性
其實本文對訊息中介軟體的叢集高可用架構的探討,是完全脫離於某個具體技術的,非常樸素的從本質的原理層面來討論這個話題。
具體的 RabbitMQ、Kafka、RocketMQ 等各種不同的訊息中介軟體,對這種高可用架構的實現,都有一定的相似想通性,但是也都有各自不同的技術實現,以及相對應的區別。
- EOF -
看完本文有收穫?請轉發分享給更多人
關注「ImportNew」,提升Java技能
點贊和在看就是最大的支援:heart: