JMS和ActiveMQ介紹(4)_ActiveMQ

183716167.jpg

下面,我們再看看ActiveMQ是如何實現高可用的。

ActiveMQ實現高可用有兩類方案:

第一類方案是構建服務器網絡,消息在服務器網絡中進行傳遞,客戶端通過failover或discovery連接網絡中的一個服務器發送或接收消息,當服務器失效時,客戶端自動重連另一個服務器。

第二類方案是構建服務器主從集羣,在某個時間只有一個服務器作爲主對外提供服務,當主服務器失效時,從服務器切換成主服務器對外提供服務,客戶端自動重連至新的主服務器。

MasterSlave有4種具體實現方案,下面將介紹一下前3種,第4種在官網上已有介紹,是基於HahaDBA和Zookeeper的,但目前還不支持該功能。

183754723.jpg

PureMaster Slave需要兩個啓動兩個ActiveMQbroker,主broker不需要做額外配置,從broker中需要作如下配置,在其中設定主broker的連接,這樣在從broker啓動後,會建立與主broker的連接,並對主broker的消息進行同步。當主broker失敗時,從broker自動切換成主broker。

另外,在使用PureMaster Slave時,需要客戶端使用failover方式連接ActiveMQbroker,並設定randomize的值爲false,這樣,客戶端在連接主broker失敗後,會自動嘗試連接從broker。

PureMaster Slave配置簡單,易於實現,之前是ActiveMQ比較推薦的高可用解決方案,但在Pure Master Slave中,消息傳送必須經過主、從服務器的確認,另外Pure Master Slave還存在以下不足:

1)主服務器只能有一個從服務器;

2)主服務器失敗重啓後,還必須重啓從服務器才能恢復主服務器;

3) 主、從服務器之間沒有自動同步機制。

我們在實踐中也遇到過由沒有自動同步機制導致的問題:有一次使用中我們創建持久訂閱者連接服務器,開始時,持久訂閱者的狀態在主從上是同步的,均爲活躍,但在做了一次重啓從服務器的操作後,從服務器中原先活躍的持久訂閱者變更爲了非活躍,與主服務器狀態不一致,所以發往主從的消息由於從服務器上訂閱者爲非活躍狀態不消費造成消息阻塞。

由於PureMaster Slave具有以上不足,因此在ActiveMQ5.8.0版本中已去掉了該功能。

183817488.jpg

使用基於JDBC的Master Slave時,多個消息服務器實例嘗試獲取數據庫排他鎖(exclusive lock),只有一個成功獲取鎖,對外提供服務,成爲主服務器,其他等待。

客戶端連接採用failover方式,從多個地址中找到當前可用的消息服務器實例並連接。

當Master失去排他鎖或失去數據庫連接時,Master將會關閉,其他服務器實例通過競爭,由一個實例獲取鎖成爲新Master,客戶端通過failover重新連接至新Master。

原Master在重新啓動後成爲Slave等待鎖。

SharedFile System MasterSlave的實現原理與JDBCMaster Slave類似,多個服務器共用一個存儲消息的文件系統(SAN);需要確認文件系統存在文件讀寫鎖,獲取讀寫鎖的服務器自動成爲主服務器,直至失敗放棄讀寫鎖;客戶端也是使用failover進行連接。

183840847.jpg

下面是關於ActiveMQ的安全機制。

ActiveMQ的安全機制包括兩部分:

驗證,通過訪問者的用戶名和密碼實現用戶身份的驗證;

授權,爲消息目標(隊列或主題)的讀、寫、管理指定具有相應權限的用戶組,併爲用戶分配權限。

ActiveMQ的安全機制基於插件實現,可以靈活配置。

ActiveMQ提供兩種驗證插件,分別是:

1)簡單驗證插件;

2)JAAS驗證插件。

ActiveMQ提供一種授權插件。

183907146.jpg

以上是簡單驗證和JAAS驗證插件的配置示例,均需要配置用戶名、用戶組和密碼。

設置插件後,在創建連接時,需要輸入賬號和密碼。

connectionFactory.createConnection(“user”,”password”);

183929146.jpg

以上是授權插件的配置示例,可以設置某一個隊列、主題或某一類隊列、主題的讀、寫、管理權限組。

184001720.jpg

下面再通過簡單驗證插件源碼介紹一下ActiveMQ的插件機制以及驗證是如何實現的

ActiveMQ的插件機制如圖所示,主要涉及BrokerPlugin和BrokerFilter這兩個接口和類。

BrokerPlugin中的installPlugin方法用於安裝插件,在installPlugin方法中會傳入Broker對象,而BrokerFilter是Broker的實現,在BrokerFilter中包含着一個對Broker的引用next,可以在installPlugin方法中,新建BrokerFilter對象,並將installPlugin方法傳入Broker對象賦值給next,這樣多個BrokerFilter對象就通過next引用形成鏈。這與struts中Interceptor的原理是類似的。

對於簡單驗證插件,在SimpleAuthenticationBroker類中,重寫了BrokerFilter的addConnnection方法,在新建連接時,若允許匿名訪問,則不進行驗證,若不允許匿名訪問,則驗證連接的用戶名和密碼是否與配置文件中的一致,若不一致,則拋出安全異常。

184025697.jpg

通知信息機制是ActiveMQ服務器通過發佈特定的通知消息記錄服務器和客戶端的操作日誌,便於系統監控。另外,ActiveMQ服務器網絡之間的通信也是基於通知消息的。

發送通知消息的操作有:

消費者、生產者和連接的創建和關閉;

隊列、主題的創建和銷燬;

消息的過期;

消息發送至無消費者的目的地址。

通知消息發佈至相應的主題上,通知消息的主題有兩類:

第一類是基於客戶端的主題,包括連接、生產者、消費者的創建和關閉,例如連接的創建和關閉消息發佈在Connection主題上;

第二類是基於目的地址和消息的主題,包括隊列、主題的創建和銷燬,消息的過期等,例如,隊列、主題的創建和銷燬消息發佈至Queue和Topic主題上。

184048153.jpg

這一頁介紹一下有關排他消費者和消息組的相關概念。

對於隊列,當有多個消費者時,消息服務器將把消息平均地發送給每個消費者,實現負載均衡,但是多個消費者接收、處理消息時並不會在線程上同步,這就導致消息在併發處理時,無法保證消息原有的順序。

排他消費者(Exclusive Consumer)是在多消費者情況下,消息服務器指定一個消費者接收消息,這樣可以保證消息的有序性。其他消費者處於等待狀態。

當原先指定的消費者無法接收消息時,消息服務器將從等待的消費者中再指定一個消費者接收消息。

排他消費者可以在多個消費者的情況下,保證消息的有序性,且在單個消費者故障時,能夠保證消息繼續被消費,但由於每次只有一個消費者消費消息,造成吞吐量低,其他消費者的資源浪費。

使用消息組(message group)可以避免排他消費者的不足。

消息組是指通過設定消息的JMSXGroupID屬性來爲消息進行分組,而同一組消息將被髮送至同一個消費者進行處理,因此可以保證在多消費者情況下,消息能夠有序處理。

184105201.jpg

之前我們討論過,對於主題,若訂閱者不連接,則存在消息丟失,若需要保證消息全部接收,則需要創建持久訂閱者,但對於持久訂閱者,由於其需要指定ClientID,因此只能保證同一個ClientID只有一個消費者、一個線程訪問主題,這就導致以下兩個問題:

無法實現消息消費的負載均衡;

消費者失敗時,不能由其他的消費者恢復。

如何同時既能實現主題的特性,同一個消息由多個消費者消費,也能實現隊列的特性,多消費者實現負載均衡?可以通過使用虛主題解決上述問題。

虛主題以VirtualTopic.主題名的形式命名,當配置虛主題後,ActiveMQ可以將該主題映射到以Consumer.隊列名.VirtualTopic.主題名的形式命名的隊列上,消息生產者仍將消息發送至主題,而ActiveMQ會將消息再轉發至隊列上,消息消費者通過使用隊列接收來自主題的消息,這樣就可以啓動多個消費者,實現負載均衡。

虛主題的配置如下所示。

184129203.jpg

ActiveMQ支持除Java以外的多種語言,包括C/C++,.NET,Perl,PHP,Python,Ruby等,對於腳本語言,一般採用STOMP協議連接ActiveMQ。

STOMP是一種類似於HTTP的協議,支持命令有:SEND,SUBSCIRBE,UNSUBSCRIBE等,在使用STOMP連接ActiveMQ時,首先需要在ActiveMQ配置STOMP連接,通常一般佔用61613端口。

以下分別是Python和PHP使用STOMP連接消息服務器並接收主題消息的示例代碼。

對於C,ActiveMQ提供C++ API和.NET API,對於Web編程,ActiveMQ提供RESTAPI和AjaxAPI,大家有興趣可以去嘗試一下。

184146195.jpg

在使用消息服務器時,有時候我們不希望ActiveMQ在單獨的JVM中運行,而是集成在已有的Java應用中。

在Java應用中嵌入ActiveMQ服務器有如下幾種方法:

創建BrokerService實例;

使用BrokerFactory方法創建BrokerService實例。

184205286.jpg


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章