目录
在ActiveMQ持久化是指消息数据持久化到磁盘中,ActiveMQ默认使保存在内存中的
当内存容量不足的时或ActiveMQ正常关闭时会将内存中未处理的消息持久化到磁盘中,具体的持久化策略由配置文件中的配置决定。
ActiveMQ的默认存储策略时kahadb。如果使用JDBC作为持久化策略,则会将所有需要持久化的信息保存到数据库中
所有的持久化配置都在conf/activemq.xml中配置,配置信息都在broker标签内部定义
1、kahadb方式
是ActiveMQ默认的持久化策略,kahadb是一个文件型数据库,是使用内存+文件保存数据的持久化。kahadb可以限制每个数据文件的大小,不代表总计数据容量
persistenceAdapter 持久化策略适配器标签
<persistenceAdapter>
<!-- directory:保存数据的目录; journalMaxFileLength:保存消息的文件大小 -->
<kahaDB directory="${activemq.data}/kahadb" journalMaxFileLength="16mb"/>
</persistenceAdapter>
特性是:1、日志形式存储消息;2、消息索引以 B-Tree 结构存储,可以快速更新;3、完全支持 JMS 事务;4、支持多种恢复机制;
db-1.log:保存数据的索引二进制文件
db.data:保存的数据文件
db.redo:提供反向操作,相当于容错
lock:保存锁信息
2、JDBC 持久化方式
activeMQ将数据持久化到数据库中,可以使用任意的数据库,本环节使用MySQL数据库作为示例
下述为 activemq.xml 配置文件部分内容
首先定义一个 mysql-ds 的 MySQL 数据源,然后在 persistenceAdapter 节点中配置jdbcPersistenceAdapter 并且引用刚才定义的数据源。
dataSource 指定持久化数据库的 bean,createTablesOnStartup 是否在启动的时候创建数据表,默认值是 true,这样每次启动都会去创建数据表了,一般是第一次启动的时候设置为true,之后改成 false。
注:ActiveMQ第一次启动,createTablesOnStartup设置为true,启动后如果不修改createTablesOnStartup设置为false,ActiveMQ将在下次启动会再重新初始化数据库,信息会丢失
<persistenceAdapter>
<jdbcPersistenceAdapter dataSource="#mysql-ds" createTablesOnStartup="false"/>
</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:3306/activemq?relaxAutoCommit=true"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
<property name="maxActive" value="200"/>
<property name="poolPreparedStatements" value="true"/>
</bean>
配置成功后,在相应的数据库中创建对应的 database【我创建的是activemq】,否则无法访问。
启动ActiveMQ后会在activemq库中自动创建相应的表
activemq_msgs :用于存储消息,Queue 和 Topic 都存储在这个表中:
ID:自增的数据库主键
CONTAINER:消息的 Destination
MSGID_PROD:消息发送者客户端的主键
MSG_SEQ:是发送消息的顺序,MSGID_PROD+MSG_SEQ 可以组成 JMS 的 MessageID
EXPIRATION:消息的过期时间,存储的是从 1970-01-01 到现在的毫秒数
MSG:消息本体的 Java 序列化对象的二进制数据
PRIORITY:优先级,从 0-9,数值越大优先级越高
activemq_acks 用于存储订阅关系。如果是持久化 Topic,订阅者和服务器的订阅关系在
这个表保存:
主要的数据库字段如下:
CONTAINER:消息的 Destination
SUB_DEST:如果是使用 Static 集群,这个字段会有集群其他系统的信息
CLIENT_ID:每个订阅者都必须有一个唯一的客户端 ID 用以区分
SUB_NAME:订阅者名称
SELECTOR:选择器,可以选择只消费满足条件的消息。条件可以用自定义属性实现,
可支持多属性 AND 和 OR 操作
LAST_ACKED_ID:记录消费过的消息的 ID。
activemq_lock 在集群环境中才有用,只有一个 Broker 可以获得消息,称为 MasterBroker,
其他的只能作为备份等待 Master Broker 不可用,才可能成为下一个 Master Broker。
这个表用于记录哪个 Broker 是当前的 Master Broker。只有在消息必须保证有效,且绝对不能丢失的时候。使用 JDBC 存储策略。
如果消息可以容忍丢失,或使用集群/主备模式保证数据安全的时候,建议使用 levelDB 或 Kahadb。