ActiveMQ 中的訊息持久化(二)

五柳-先生發表於2015-11-18
為了長時間的儲存和管理訊息,一般會使用資料庫。在Activemq中預設使用的是Derby DB。當然也可更改配置來使用其他的DB。Activemq支援以下這些DB: 
  • Apache Derby
  • Axion
  • DB2
  • HSQL
  • Informix
  • MaxDB
  • MySQL
  • Oracle
  • Postgresql
  • SQLServer
  • Sybase

     如果要使用不在上面列表中的DB,可以通過配置SQL語句和JDBC驅動來支援自己的DB。Broker在啟動的時候讀取配置檔案,若在配置檔案中指定了特定的JDBC驅動,則會在classpath路徑下自動檢測配置的JDBC驅動。下面是關於oracle的一個配置: 
Xml程式碼  收藏程式碼
  1. <beans ...>  
  2.   <broker xmlns="http://activemq.apache.org/schema/core"  
  3.           brokerName="localhost">  
  4.     ...  
  5.     <persistenceAdapter>  
  6.        <jdbcPersistenceAdapter  
  7.             dataDirectory="${activemq.base}/data"  
  8.             dataSource="#oracle-ds"/>  
  9.     </persistenceAdapter>  
  10.     ...  
  11.   </broker>  
  12.    
  13.   <!-- Oracle DataSource Sample Setup -->  
  14.   <bean id="oracle-ds"  
  15.         class="org.apache.commons.dbcp.BasicDataSource"  
  16.         destroy-method="close">  
  17.     <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>  
  18.     <property name="url" value="jdbc:oracle:thin:@localhost:1521:AMQDB"/>  
  19.     <property name="username" value="scott"/>  
  20.     <property name="password" value="tiger"/>  
  21.     <property name="maxActive" value="200"/>  
  22.     <property name="poolPreparedStatements" value="true"/>  
  23.   </bean>  
  24.   
  25. </beans>  

在InstallDir/conf/activemq-jdbc.xml有一個jdbc配置樣例。 

在使用JDBC持久化的時候根據是否支援Activemq提供的高效的journal檔案分為兩種。 
1、支援高效日誌 
在訊息消費者能跟上生產者的速度時,journal檔案能大大減少需要寫入到DB中的訊息。舉個例子:生產者產生了10000個訊息,這10000個訊息會儲存到journal檔案中,但是消費者的速度很快,在journal檔案還未同步到DB之前,以消費了9900個訊息。那麼後面就只需要寫入100個訊息到DB了。如果消費者不能跟上生產者的速度,journal檔案可以使訊息以批量的方式寫入DB中,JDBC驅動進行DB寫入的優化。從而提升了效能。另外,journal檔案支援JMS事務的一致性。 
下面是一段支援高效日誌的JDBC持久化的配置: 
Xml程式碼  收藏程式碼
  1. <beans ...>  
  2.   <broker ...>  
  3.     ...  
  4.   <persistenceFactory>  
  5.     <journaledJDBC journalLogFiles="5" dataSource="#mysql-ds" />  
  6.     </persistenceFactory>  
  7.     ...  
  8.   <broker>  
  9.   ...  
  10. <bean id="mysql-ds"  
  11.       class="org.apache.commons.dbcp.BasicDataSource"  
  12.       destroy-method="close">  
  13.     <property name="driverClassName" value="com.mysql.jdbc.Driver"/>  
  14.     <property name="url" value="jdbc:mysql://localhost/activemq?relaxAutoCommit=true"/>  
  15.     <property name="username" value="activemq"/>  
  16.     <property name="password" value="activemq"/>  
  17.     <property name="poolPreparedStatements" value="true"/>  
  18.   </bean>  
  19. </beans>  

journaledJDBC 節點的有以下可配置屬性: 
屬性 預設值 描述
adapter   指定持久儲存的DB
createTablesOnStartup true 是否在啟動的時候建立相應的表
dataDirectory activemq-data 指定Derby儲存資料檔案的路徑
dataSource #derby 指定要引用的資料來源
journalArchiveDirectory   指定歸檔日誌檔案儲存的路徑
journalLogFiles 2 指定日誌檔案的數量
journalLogFileSize 20MB 指定每個日誌檔案的大小
journalThreadPriority 10 指定寫入日誌的執行緒的優先順序
useDatabaseLock true 在主從配置的時候是否使用排他鎖
useJournal true 指定是否使用日誌

2、不使用高效日誌 
下面是不使用高效日誌的配置: 
Xml程式碼  收藏程式碼
  1. <beans ...>  
  2.   <broker ...>  
  3.   ...  
  4.   <persistenceAdapter>  
  5.     <jdbcPersistenceAdapter dataSource="#derby-ds" />  
  6.     </persistenceAdapter>  
  7.     ...  
  8.   <broker>  
  9.   ...  
  10. <bean id="derby-ds" class="org.apache.derby.jdbc.EmbeddedDataSource">  
  11.     <property name="databaseName" value="derbydb"/>  
  12.     <property name="createDatabase" value="create"/>  
  13.   </bean>  
  14. </beans>  

可以看出,使用高效日誌的配置使在persistenceFactory節點內的。而不使用高效日誌的使配置在persistenceAdapter節點內的。 
下面是jdbcPersistenceAdapter 節點可配置的屬性: 
屬性 預設值 描述
adapter   指定持久儲存的DB
cleanupPeriod 300000 指定刪除DB中已收到確認資訊的訊息的時間週期(ms)
createTablesOnStartup true 是否在啟動的時候建立相應的表
databaseLocker DefaultDatabaseLocker instance 防止多個broker同時訪問DB的鎖例項
dataDirectory activemq-data 指定Derby儲存資料檔案的路徑
dataSource #derby 指定要引用的資料來源
lockAcquireSleepInterval 1000 等待獲取鎖的時間長度(ms)
lockKeepAlivePeriod 30000 定期向lock表中寫入當前時間,指定了鎖的存活時間
useDatabaseLock true 在主從配置的時候是否使用排他鎖
transactionIsolation Connection.TRANSACTION_READ_UNCOMMITTED 指定事務隔離級別

如果需要配置的DB不再Activemq預設支援的DB列表中,可以通過配置SQL語句和JDBC持久層來實現。在journaledJDBC節點下配置statements 節點來指定JDBC持久層對各類資料的處理方式。下面是一個樣例: 
Xml程式碼  收藏程式碼
  1. <persistenceFactory>  
  2.   <journaledJDBC ...>  
  3.     <statements>  
  4.       <statements stringIdDataType ="VARCHAR(128)"/>  
  5.     </statements>  
  6.   </journaledJDBC>  
  7. </persistenceFactory>  

statements 節點的各個屬性: 
屬性 預設值 描述
tablePrefix   指定建立的表名的字首
messageTableName ACTIVEMQ_MSGS 儲存訊息內容的表名
durableSubAcksTableName ACTIVEMQ_ACKS 儲存持久訂閱者的確認訊息的表名
lockTableName ACTIVEMQ_LOCK lock表名
binaryDataType BLOB 指定存放訊息的資料型別
containerNameDataType VARCHAR(250) 指定存放Destination名稱的資料型別
msgIdDataType VARCHAR(250) 存放訊息ID的資料型別
sequenceDataType INTEGER 存放訊息序列ID的資料型別
longDataType BIGINT DB中存放JAVA中long型的資料型別
stringIdDataType VARCHAR(250) 存放長字串的DB資料型別


定製自己插入和讀取資料的SQL語句,可以設定下面的這些屬性 
  • addMessageStatement
  • updateMessageStatement
  • removeMessageStatement
  • findMessageSequenceIdStatement
  • findMessageStatement
  • findAllMessagesStatement
  • findLastSequenceIdInMsgsStatement
  • findLastSequenceIdInAcksStatement
  • createDurableSubStatement
  • findDurableSubStatement
  • findAllDurableSubsStatement
  • updateLastAckOfDurableSubStatement
  • deleteSubscriptionStatement
  • findAllDurableSubMessagesStatement
  • findDurableSubMessagesStatement
  • findAllDestinationsStatement
  • removeAllMessagesStatement
  • removeAllSubscriptionsStatement
  • deleteOldMessagesStatement
  • lockCreateStatement
  • lockUpdateStatement
  • nextDurableSubscriberMessageStatement
  • durableSubscriberMessageCountStatement
  • lastAckedDurableSubscriberMessageStatement
  • destinationMessageCountStatement
  • findNextMessageStatement
  • createSchemaStatements
  • dropSchemaStatements

設定adapter屬性可以設定JDBC介面卡儲存和訪問BLOB欄位的方式,可設定的方式有: 
  • org.activemq.store.jdbc.adapter.BlobJDBCAdapter
  • org.activemq.store.jdbc.adapter.BytesJDBCAdapter
  • org.activemq.store.jdbc.adapter.DefaultJDBCAdapter
  • org.activemq.store.jdbc.adapter.ImageJDBCAdapter

具體需要檢視JDBC的驅動資料庫的文件。 
Xml程式碼  收藏程式碼
  1. <broker persistent="true" ...>  
  2.   ...  
  3.   <persistenceFactory>  
  4.     <journaledJDBC adapter="org.activemq.store.jdbc.adapter.BlobJDBCAdapter" ... />  
  5.   </persistenceFactory>  
  6.   ...  
  7. </broker>  

轉載: http://berdy.iteye.com/blog/813794

相關文章