ActiveMQ不仅支持persistent和non-persistent两种方式,而其ActiveMQ还支持消息的recovery(恢复)方式。
消息发送到Queue和Topic的存储原理和结构是不同的,ActiveMQ主要支持以下几种方式:
· AMQ消息存储-默认的消息存储。
· KahaDB消息存储-提供了容量的提升和恢复能力。
· JDBC消息存储-消息基于JDBC存储。
· Memory消息存储-基于内存的消息存储。
JDBC Message Store
ActiveMQ使用JDBC时默认的驱动是Apache Derby数据库。同时也支持其他关系型数据库:MySQL、Oracle、SQLServer、Sybase等。
MySQL配置:
<broker brokerName="mysql-broker" xmlns="http://activemq.apache.org/schema/core">
<persistenceAdapter>
<jdbcPersistenceAdapter dataSource="#mysql-ds"/>
</persistenceAdapter>
</broker>
<bean id="mysql-ds" class="org.apache.commons.dbcp.BasicDataSource" destroy- method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost/activemq?relaxAutoCommit=true"/>
<property name="username" value="us"/>
<property name="password" value="ps"/>
<property name="maxActive" value="200"/>
<property name="poolPreparedStatements" value="true"/>
</bean>
Oracle配置:
<broker brokerName="oracle-broker" xmlns="http://activemq.apache.org/schema/core">
<persistenceAdapter>
<jdbcPersistenceAdapter dataSource="#oracle-ds"/>
</persistenceAdapter>
</broker>
<bean id="oracle-ds" class="org.apache.commons.dbcp.BasicDataSource" destroy- method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@localhost:1521:activemq"/>
<property name="username" value="us"/>
<property name="password" value="ps"/>
<property name="maxActive" value="200"/>
<property name="poolPreparedStatements" value="true"/>
</bean>
选择一种数据库,配置完成后,启动AactiveMQ,数据库中会自动生成三张表,其中两张表用于存储消息、第三张表用于进行同步操作:
**ACTIVEMQ_MSGS:**用于存放消息内容
列名 | 数据类型 | 注释 |
---|---|---|
ID | INTEGER | 数据主键。 |
CONTAINER | VARCHAR(250) | 消息目的地。 |
MSGID_PROD | VARCHAR(250) | 生产者标识。 |
MSGID_SEQ | INTEGER | 生产者生成的消息序列。MSGID_PROD+MSGID_SEQ=JMSMessageID。 |
EXPIRATION | BIGINT | 消息有效期。 |
MSG | BLOB | 消息内容。 |
PRIORITY | INTEGER | 消息优先级,0-9。 |
**ACTIVEMQ_ACKS:**用于存储订阅关系
列名 | 数据类型 | 注释 |
---|---|---|
CONTAINER | VARCHAR(250) | 消息目的地。 |
SUB_DEST | VARCHAR(250) | 持久订阅目的地。 |
CLIENT_ID | VARCHAR(250) | 持久订阅的客户端ID。 |
SUB_NAME | VARCHAR(250) | 持久订阅者名称。 |
SELECTOR | VARCHAR(250) | 持久订阅选择器。可以通过选择器选择感兴趣的消息进行订阅。 |
LAST_ACKED_ID | INTEGER | 订阅者最后接收的消息ID。 |
**ACTIVEMQ_LOCK:**只有在集群环境下才会用,只有一个Broker可以获得消息,称为Master Broker。
列名 | 数据类型 | 注释 |
---|---|---|
ID | INTEGER | 数据主键,标识锁的唯一标识 |
BROKER_NAME | VARCHAR(250) | Master Broker,获取锁的Broker的名称 |
JDBC Message Store with Journal
它克服了JDBC Message Store的不足,快速的写入,大大提高了性能。
derby配置:
<broker brokerName="derby-broker" xmlns="http://activemq.apache.org/schema/core">
<persistenceAdapter>
<journaledJDBC dataDirectory="${activemq.base}/data" dataSource="#derby-ds"
</persistenceAdapter>
</broker>
<bean id="derby-ds" class="org.apache.derby.jdbc.EmbeddedDataSource">
<property name="databaseName" value="derby"/>
<property name="createDatabase" value="create"/>
</bean>
JDBC Message Store 与 JDBC Message Store with Journal 区别
· JDBC Message Store with Journal的性能由于JDBC Message Store。
· JDBC Message Store用于Master/Slave模式的数据库分享。
· JDBC Message Store with Journal不能用于Master/Slave模式。
· 一般情况下,推荐使用JDBC Message Store with Journal。
JDBC Message Store应用场景:
使用此方案的原因是因为数据库已经存在,JDBC Message Store性能并不是很好。但是JDBC Message Store可以用于Master/Slave模式,当一组Broker使用一个共享数据库时,可以使用排它锁达到并发的目的。
JDBC Message Store with Journal应用场景:
JDBC Message Store with Journal中Journal对于JDBC Message Store是一个很大的优势,仅仅在需要使用Master/Slave时,使用JDBC Message Store方案。