ActiveMQ消息存儲持久化詳解

在上一篇文章中,我們詳細介紹了ActiceMQ的功能作用以及代碼實現。本文,我們繼續來對ActiveMQ的消息存儲方式進行進一步的研究。作爲一個消息中中間件,當消費者或者發佈者將消息生成或者發佈後,這個消息需要暫存到一個地方,用於過渡,然後交給消費者或者訂閱者。那麼這些消息在中途存到哪裏去了呢?我們本章就來探討一下。
閱讀本文前,請保證已經閱讀過了《消息隊列的實現原理和ActiveMQ詳解》這篇文章,或者你已經對ActiveMQ有了充分的學習和認識。

ActiveMQ消息存儲持久化

在這裏插入圖片描述
如圖所示,ActiveMQ提供了插件式的消息存儲,主要有如下幾種:

  1. AMQ Message Store:AMQ消息存儲-基於文件的存儲方式,是以前的默認消息存儲

  2. kahaDB Message Store:KahaDB消息存儲-提供了容量的提升和恢復能力,是現在的默認存儲方式

  3. JDBC Store:JDBC消息存儲-消息基於JDBC存儲的

  4. Memory Message Store:Memory消息存儲-基於內存的消息存儲

關於ActiceMQ的所有配置信息,都配置在置activemq.xml文件中,這個文件在安裝成功後的根路徑下的conf目錄下,打開即可修改。爲什麼要提到這個文件,那肯定是一會所有的配置都要圍繞它展開,如果不知道它在哪,將沒有辦法對它進行修改,只能使用默認配置~
下面就來分別介紹一下這幾種方式。

(1) KahaDB Message Store 概述

KahaDB是目前默認的存儲方式,可用於任何場景,提高了性能和恢復能力。消息存儲使用一個事務日誌和僅僅用一個索引文件來存儲它所有的地址。

KahaDB是一個專門針對消息持久化的解決方案,它對典型的消息使用模式進行了優化。在kaha中,數據被追加到 data logs(數據日誌)中。 當不再需要log文件中的數據的時候,log(日誌)文件會被丟棄。

KahaDB基本配置如下:

<persistenceAdapter> 
	<kahaDB directory="${activemq.data}/kahadb"/>
</persistenceAdapter>

這個配置是默認的,如果不做任何修改,你在打開配置文件後看到的就是這個樣子。

當然,這種配置方式下,還有需要可用的屬性。這裏默認只有一個directory屬性,下面來介紹一下這裏的可用屬性:

  1. director: KahaDB存放的路徑,默認值activemq-data
  2. indexWriteBatchSize: 批量寫入磁盤的索引page數量,默認值爲1000
  3. indexCacheSize: 內存中緩存索引page的數量,默認值10000
  4. enableIndexWriteAsync: 是否異步寫出索引,默認false
  5. journalMaxFileLength: 設置每個消息data log的大小,默認是32MB
  6. enableJournalDiskSyncs: 設置是否保證每個沒有事務的內容,被同步寫入磁盤,JMS持久化的時候需要,默認爲true
  7. cleanupInterval: 在檢查到不再使用的消息後,在具體刪除消息前的時間,默認30000
  8. checkpointInterval: checkpoint的間隔時間,默認是5000
  9. ignoreMissingJournalfiles: 是否忽略丟失的消息日誌文件,默認false
  10. checkForCorruptJournalFiles: 在啓動的時候,將會驗證消息文件是否損壞,默認false
  11. checksumJournalFiles: 是否爲每個消息日誌文件提供checksum,默認false
  12. archiveDataLogs: 是否移動文件到特定的路徑,而不是刪除它們,默認false
  13. directoryArchive: 定義消息已經被消費過後,移動data log到的路徑,默認null
  14. databaseLockedWaitDelay: 獲得數據庫鎖的等待時間(used by shared master/slave),默認10000
  15. maxAsyncJobs: 設置最大的可以存儲的異步消息隊列,默認值10000,可以和concurrent MessageProducers設置成一樣的值。
  16. concurrentStoreAndDispatchTransactions:是否分發消息到客戶端,同時事務存儲消息,默認true
  17. concurrentStoreAndDispatchTopics:是否分發Topic消息到客戶端,同時進行存儲,默認true
  18. concurrentStoreAndDispatchQueues: 是否分發queue消息到客戶端,同時進行存儲,默認true

(2) AMQ Message Store 概述

AMQ Message Store是ActiveMQ5.0的持久化存儲,它是一個基於文件、事務存儲設計爲快速消息存儲的一個結構,該結構是以流的形式來進行消息交互的。
這種方式中,Messages被保存到data logs中,同時被reference store進行索引以提高存取速度。Data logs由一些簡單的data log文件組成,缺省的文件大小是32M,如果某個消息的大小超過了data log文件的大小,那麼可以修改配置以增加data log文件的大小。如果某個data log文件中所有的消息都被成功消費了,那麼這個data log文件將會被標記,以便在下一輪的清理中被刪除或者歸檔。

AMQ Message Store基本配置如下:

<broker brokerName="broker" persistent="true" useShutdownHook="false">
	<persistenceAdapter>
		<amqPersistenceAdapter directory="${activemq.base}/data" maxFileLength="32mb" />
	</persistenceAdapter>
</broker>

(3) 使用JDBC來持久化消息

JDBC Store方式

ActiveMQ支持使用JDBC來持久化消息,預定義的表如下:

  1. 消息表,表名爲ACTIVEMQ_MSGS, queue和topic都存儲在裏面,結構如下:
    在這裏插入圖片描述
  2. ACTIVEMQ_ACKS表,存儲持久訂閱的信息和最後一個持久訂閱接收的消息ID,結構如下:
    在這裏插入圖片描述
  3. 鎖定表,表名爲ACTIVEMQ_LOCK,用來確保在某一時刻,只能有一個ActiveMQ broker實例來訪問數據庫,結構如下:
使用JDBC來持久化消息的配置示例:

在activemq.xml中的配置如下:

	<persistenceAdapter>
	   <jdbcPersistenceAdapter dataSource="#mysql-ds" />
	</persistenceAdapter>

這裏基本的配置就是將默認的KahaDB配置註解刪除,換成上面的註解。當然,這裏可以對數據庫進行配置,例如可以添加 transactionIsolation=“4” 事務隔離級別,useDatabaseLock=“false” 是否開啓數據庫鎖等。
另外,這裏的將持久化方式配置成數據庫後,我們就需要創建一個數據庫的配置,用來供給ActiveMQ對接存儲數據,我們可以直接在當前的activemq.xml配置文件中創建一個< bean >標籤來定義數據庫的配置信息。此處配置的是一個數據源對象,運用的數據源實現產品是dbcp,因爲這是ActiceMQ自帶的一種數據源實現方式。

代碼:

<bean id="mysql-ds" class="org.apache.commons.dbcp2.BasicDataSource"  destroy-method="close">  
	<property name="driverClassName" value="com.mysql.jdbc.Driver" />  
	<property name="url"  value="jdbc:mysql://localhost:3306/test" /> 
	<property name="username" value="root" />  
	<property name="password" value="root" />  
	<property name="initialSize" value="5" />  
	<property name="maxTotal" value="100" />  
	<property name="maxIdle" value="30" />  
	<property name="maxWaitMillis" value="10000" />  
	<property name="minIdle" value="1" /> 
</bean>

重點強調:

  1. bean 對象的 id 要與一開始修改ActiveMQ的持久化方式時,使用的
    < jdbcPersistenceAdapter dataSource="#mysql-ds" /> 中指定的dataSource的id保持一致。dataSource給了#mysql-ds,那麼#就是id,所以我們的數據源bean就得有id屬性,同時,id的值就是#後面的值,必須對應一致,但是不一定非要按照我寫的來,名字可以隨便。
  2. 可以看出來,我在這裏使用的mysql數據庫,使用數據庫持久化的方式肯定離不開JDBC的實現,所以,我們必須將mysql的jdbc jar包(mysql-connector-java-5.1.38.jar),拷貝到ActiveMQ的根路徑下的lib目錄中,以備啓動ActiveMQ時,它與數據庫進行鏈接,如果沒有,將無法鏈接。

完成上面的配置和jar包的引入,就可以在開發過程中直接使用了,使用的方法就是在使用MessageProducer消息生產者/發佈者時,將持久化方式進行修改。代碼如下:

//設置消息持久化
producer.setDeliveryMode(DeliveryMode.PERSISTENT);

JDBC Message Store with ActiveMQ Journal 方式

這種方式克服了JDBC Store的不足,使用快速的緩存寫入技術,大大提高了性能。

配置如下

<beans>
  <broker brokerName="test-broker" xmlns="http://activemq.apache.org/schema/core">
     <persistenceFactory>
     	<journalPersistenceAdapterFactory journalLogFiles="4" journalLogFileSize="32768"
       		useJournal="true" useQuickJournal="true" dataSource="#mysql_ds" dataDirectory="activemq-data">
    </persistenceFactory>
  </broker>
</beans>
JDBC Store和JDBC Message Store with ActiveMQ Journal的區別:
  1. JDBC with journal的性能優於jdbc
  2. JDBC用於master/slave模式的數據庫分享
  3. JDBC with journal不能用於master/slave模式
  4. 一般情況下,推薦使用jdbc with journal

(4) 使用 Memory Message Store 方式持久化

內存消息存儲主要是存儲所有的持久化的消息在內存中。這裏沒有動態的緩存存在,所以你必須注意設置你的broker所在的JVM和內存限制。

配置

<beans>
   <broker brokerName="test_broker" persistent="false" xmlns="http://activemq.apache.org/schema/core">
    <transportConnectors>
     	<transportConnector uri="tcp://localhost:61635">
     </transportConnectors>
   </broker>
</beans>
發佈了14 篇原創文章 · 獲贊 3 · 訪問量 2093
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章