常見訊息中介軟體之ActiveMQ

勝金發表於2020-09-23

前言

  訊息佇列是指利用高效可靠的訊息傳遞機制進行與平臺無關的資料交流,並基於資料通訊來進行分散式系統的整合。目前訊息佇列已經逐漸成為企業IT系統內部通訊的核心手段,它具有低耦合、可靠投遞、廣播、流量控制、最終一致性等一系列功能,成為非同步RPC的主要手段之一。當前使用較多的訊息佇列有RabbitMQ、RocketMQ、ActiveMQ、Kafka、ZeroMQ、MetaMQ等,而部分資料庫如Redis、MySQL以及phxsql也可實現訊息佇列的功能。

  大多時候,我們使用訊息佇列來做三件事情:解耦、削峰、非同步。這是訊息佇列最突出的優點,其他優點比如可以持久化資料,保證訊息之間的順序等等在業務中對我們的幫助也很大。

  萬事有利就有弊,訊息佇列有這些優點,自然也有它的缺點,比如:

  1)系統研發成本增加。引入訊息佇列後,你就必須要對大多數訊息佇列有個深入的理解,否則如何做技術選型呢?而訊息佇列本身也比較複雜,在短時間內無法完全理解。所以是否使用訊息佇列需要根據具體場景判斷,而不是為了使用技術而用技術。

  2)系統複雜性增加。 一個系統如果直接將業務序列處理,那麼只需要在一個系統中把程式碼寫寫寫就好了。但如果引入訊息佇列,則要多考慮很多方面的問題,比如一致性問題、如何保證訊息不被重複消費,如何保證保證訊息可靠傳輸。因此,需要考慮的東西更多,系統複雜性增大。

  3)系統可用性降低。 本來其他系統只要執行好好的,那你的系統就是正常的。現在你要加個訊息佇列進去,那訊息佇列掛了,你的系統勢必受到影響。因此,系統可用性降低。

  所以我們在考慮使用訊息佇列的時候,一定要對目前的主流框架有所瞭解,充分應用其優點,避免或弱化其缺點。

  當今市面上主流的開源MOM(Message Oriented Middleware,訊息中介軟體)基本上都是Apache旗下的專案,有老牌的ActiveMQ、RabbitMQ,炙手可熱的Kafka,阿里巴巴自主開發RocketMQ等。我們主要談談這幾個MQ的效能、優缺點和相應的業務場景。這些MQ都是支援叢集架構模式的。

  另外說一下Redis的MQ功能,它完全可以當做一個輕量級的佇列服務來使用。與RabbitMQ相比,入隊時,當資料比較小時 Redis 的效能要高於 RabbitMQ,而如果資料大小超過了 10K,Redis 效能就大幅度降低,很難滿足系統的使用需求;出隊時,無論資料大小,Redis 都表現出非常好的效能,而 RabbitMQ 的出隊效能則遠低於 Redis。在我們印象中,Redis 是一個 key-value 快取中介軟體,而不是一個訊息佇列中介軟體,基於以上兩種原因,我們在考慮訊息中介軟體的時候一般都不考慮 Redis。所以我們在下面的內容就不涉及Redis的相關內容了,感興趣的小夥伴可以去研究一下。

1 JMS規範

  首先我們聊聊JMS(Java Message Service)規範,也就是Java訊息服務,它定義了Java中訪問訊息中介軟體的介面規範。所以我們應該明白,JMS只是介面,並沒有給予實現,實現JMS介面的訊息中介軟體稱為“JMS Provider”。上面說到的ActiveMQ、RabbitMQ、Kafka、RocketMQ都基本遵循或參考了JMS規範,都有自己的特點和優勢。

1.1 專業術語

  JMS(Java Message Service):實現JMS介面的訊息中介軟體;

  Provider(MessageProvider):訊息的生產者;

  Consumer(MessageConsumer):訊息的消費者;

  PTP(Point to Point):點對點消費模型;

  Pub/Sub(Publish/Subscribe):釋出/訂閱的訊息模型;

  Queue:佇列目標,也就是我們說的訊息佇列,一般會真正的進行物理儲存;

  Topic:主題目標;

  ConnectionFactory:連線工廠,用於建立連線到訊息中介軟體的連線;

  Connection:JMS客戶端到JMSProvider之間的通訊鏈路;

  Destination:目的地,指訊息釋出和接收的地點,包括佇列和主題;

  Session:會話,表示一個單執行緒的上下文,用於傳送和接收訊息

1.2 JMS訊息格式

  StreamMessage 原始值的資料流

  MapMessage 一套名稱/值對

  TextMessage 一個字串物件

  BytesMessage 一個未解釋的資料流

  ObjectMessage 一個序列化的物件

2 ActiveMQ

  ActiveMQ是一個完全支援JMS1.1和J2EE1.4規範的JMS Provider實現,儘管JMS規範出臺已經很久了,但是JMS在早些年的J2EE應用中有著特殊的地位。可以說ActiveMQ是一個“古老”的訊息中介軟體了,在那個時候它在業界應用的最廣泛,也是曾經叱吒風雲過的。但是從當今的業務需求來看,ActiveMQ想要有更強大的效能和海量資料處理能力,還需要不斷升級版本,提升效能和架構設計的重構。

  ActiveMQ有豐富的API、多種叢集構建模式,這些足夠滿足我們80%以上的業務需求,事實也確實如此,做為業界老牌的訊息中介軟體,它在中小型企業應用廣泛。當然了,面對大規模、高併發應用服務做中介軟體選項,如淘寶、京東等大型電商網站,ActiveMQ就捉襟見肘了。

2.1 訊息投遞模式

  我們先說JMS規範裡最經典的兩種訊息投遞模式:“點對點”和“釋出訂閱”。

  1)點對點:生產者向佇列投遞一條訊息,只有一個消費者能夠監聽得到這條訊息(PTP),如下圖:

 

 

   2)釋出訂閱:生產者向佇列投遞一條訊息,所有監聽該佇列的消費者都能夠監聽到這條訊息(P/S),如下圖:

 

 

 2.2 指標

  我們從服務效能、儲存堆積能力、可擴充套件性三個方面考慮。

  1)ActiveMQ的效能一般,在早期傳統行業盛行的時代比較流行,但是面對如今的高併發、大資料的業務場景,就力不從心了。

  2)資料儲存預設採用kahadb儲存(索引檔案形式儲存),也可以使用高效能的google leveldb(記憶體資料庫儲存),或者使用關係型資料庫如Oracle、MySQL等儲存。

  3)ActiveMQ可以與Zookeeper進行構建主備叢集模型,並且多套的主備模型直接可以採用Network的方式構建分散式叢集。

2.3 ActiveMQ叢集

  ActiveMQ最經典的兩種叢集架構模式:Master-Slave、Network。

  1)Master-Slave:

 

 

   從名字就可以看出來就是主從方式,也就是主備方式,雙機熱備機制。Master-Slave就是訊息被複制到slave broker,即使master broker遇到故障失去工作能力,你也可以切換到slave broker繼續工作且不丟失訊息。Master-Slave數目前ActiveMQ推薦的高可靠性和容錯的解決方案。

  Master-Slave叢集的關鍵點:

  a、上圖綠色節點是主節點,灰色是備份節點,這兩個節點都是執行狀態。

  b、zookeeper的作用就是當綠色主節點當機時,進行及時切換到備份節點上去,使其進行主從角色互換,用於實現高可用性的方案。

  c、Master-Slave叢集模型的缺點也很明顯,就是不能做到分散式的topic、queue,當訊息量巨大時,我們的MQ叢集壓力過大,沒辦法滿足分散式的需求。

  2)Network

 

   可以理解為網路通訊方式。這種方式真正解決了分散式訊息儲存和故障轉移、broker切換的問題。它支援分散式的topic、queue。一個broker會相同對待所有的訂閱:不管他們是來自本地客戶連線,還是遠端broker,它都會遞送有關的資訊拷貝到每個訂閱。遠端broker得到這個資訊拷貝後,會依次把它遞送到其內部的本地連線上。

  Network叢集的關鍵點:

  a、這種方案需要兩套及以上的Master-Slave叢集模型才可以搞定,部署很麻煩。

  b、Network解決了分散式訊息佇列的問題,但是資源浪費嚴重。所以Master-Slave模型是傳統型網際網路公司的首選。

 

  ActiveMQ畢竟是Apache的頂級專案之一,它開箱即用,類似於 RabbitMQ,少量程式碼就可以高效地實現高階應用場景。目前正在進行新版本重構與落地,我們期待它能夠完成這次新生吧。

 

相關文章