Activemq 的消息存储持久化:
  • 开启事务
  • 设置持久
  • 设置签收方式
  • 可持久化
什么是可持久化:

为了避免意外宕机丢失信息,需要做到重启后可以恢复消息队列。消息系统一般都会采用持久化机制。Activemq 的消息持久化机制有 JDBC AMQ KahaDB 和 LevelDB ,无论使用哪种持久化方式,消息的存储逻辑是一致的。

就是发送者消息发送后,消息中心首先将消息存储在本地数据文件,内存数据库或远程数据库等 再试图将消息发送给接收者,成功则将消息从存储中删除,失败则尝试发送。

消息中心启动以后首先要检查指定的存储位置,如果有未发送的消息,则需要把消息发送出去。

持久化存储方式:

存储方式

说明

AMQ Message Store

基于文件的存储方式,是以前的默认消息存储,现在不用了(5.3之前的版本)

KahaDB(消息存储,默认)

基于日志文件,从activemq 5.4 开始默认的持久化插件

JDBC 消息存储

基于第三方数据库的消息存储

LevelDB 消息存储

未成熟

JDBC Message Store with Activemq Journal

JDBC 消息存储的升级版,解决了读写性能的问题

KahaDB

默认的消息持久化存储方式。在activemq.xml中的配置如下:

<persistenceAdapter>
        <kahaDB directory="${activemq.data}/kahadb"/>
    </persistenceAdapter>
  • KahaDB 是目前默认的存储方式,可用于任何场景,提高了性能和恢复能力。
  • 消息存储使用一个事务日志和索引文件来存储它所有的地址。
  • KahaDB 是一个专门针对消息持久化的解决方案,它对典型的消息使用模式进行了优化。
  • 数据被追加到data.log中。当不再需要log文件中的数据时,log文件将会被丢弃。
kahadb 存储原理:
  1. db - .log : KahaDB 存储消息到预定义大小的数据记录文件中,文件命名为 db.log。当文件已满时,一个新的文件会随之创建,number 数值也会随之递增,当不再有引用到数据文件中的任何消息时,文件会被删除归档。
  2. db.data 该文件包含了持久化的BTree 索引,索引了消息数据记录的消息,它是消息的索引文件,本质上是B-Tree,使用B - Tree 作为索引指向 db - .log 里面存储的消息。
  3. db.free 当前 db.data 文件有哪些页面是空闲的,文件具体内容是所有空闲页的ID。
  4. db.redo 用来进行消息恢复,如果kahaDB 消息存储在强制退出后启动,用于恢复BTree 索引。
  5. lock 文件锁,表示当前获得 kahadb 读写权限的 borker 。
LevelDB

未成熟

JDBC 消息存储

使用第三方数据库进行消息的存储。
具体步骤:

  1. 将数据库驱动包,添加到 lib 文件夹下。
  2. jdbc 配置:
<persistenceAdapter>
        <jdbcpersistenceAdapter dataSource="#jymmysql"/>
    </persistenceAdapter>

dataSource : 指定将要引用的持久化数据库的bean 名称,createTableOnStartup 是否在启动的时候创建数据表,默认值是true。这样每次启动都会去创建数据表了。一般是第一次启动设置为true,之后设置为false。

  1. 配置bean
<bean id="jymmysql" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://127.0.0.1:3306/activemq?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&relaxAutoCommit=true"/>
        <property name="username" value="root"/>
        <property name="password" value="admin"/>
        <property name="poolPreparedStatements" value="true"/>
 </bean>
  1. 数据库中新建 activemq 数据库
  2. 启动 activemq 就会自动在activemq 库中创建三张表.
jdbc存储在点对点(queue) 类型中:

当 DeliveryMode 设置为 DeliveryMode.PERSISTENT 时,会保存在数据库(activemq_msgs)中。

当 DeliveryMode 设置为 DeliveryMode.NON_PERSISTENT 时,会保存在内存中。

并且消息一旦被消费,就会从 borker 中删除

topic 类型中:

先启动消费者订阅 然后再生产的情况下 将消息保存到 activemq_acks。

JDBC with Journal(高性能)

修改配置文件:

<!--消息存储持久化JDBC message store with activemq journal-->
<persistenceFactory>
	<journalPersistenceAdapterFactory 
		journalLogFiles="4" 
		journalLogFileSize="32768" 
		useJournal="true" 
		useQuickJournal="true"
		dataSource="#jymmysql"
		dataDirectory="activemq-data"/>
</persistenceFactory>

这种方式克服了 JDBC Store 的不足,JDBC 每次消息过来,都需要去写库和读库。

Activemq Journal 使用高速缓存技术写入技术,大大提高了性能。

当消费者的消费速度能够及时跟上生产者消息的生产速度时,Journal 文件就能大大减少 DB 中的消息。