ActiveMQ学习笔记6——持久化机制

1.什么是ActiveMQ的持久化

为了避免MQ服务器意外宕机后丢失数据,需要做到重启服务器后能够回复消息队列,消息系统一般会采用持久化机制来保证系统的高可用。通俗的来说就是,当服务器挂了以后,消息不会丢失的机制。

ActiveMQ的消息持久化机制有AMQ、KahaDB、JDBC和LevelDB,无论使用那种持久化方式,消息的存储逻辑都是一致的。

整体流程如下:

  发送者将消息发送出去后,消息中心或者消息服务器首先将消息存储到本地数据文件、内存数据库或者远程数据库等。再试图将消息发送给接受者,成功则将消息从存储中删除,失败则继续尝试发送。消息中心启动后,需要先检查至此那个的存储位置是否有未成功发送的消息,如果有,则会先把存储位置中的消息发送出去。

所有持久化配置都在conf/activemq.xml中配置,配置信息都在broker标签内部定义。

2.各种持久化机制

(1)AMQ Message Store

AMQ是在ActiveMQ5.3之前版本默认使用的,基于日志文件的存储机制。

persistenceAdapter>
    <!--directory:保存数据的目录;journalMaxFileLength:保存消息的文件大小-->
    amqPersistenceAdapter directory="${activemq.data}/amq" maxFileLength="32mb" />
</persistenceAdapter>

AMQ基于文件存储形式,性能高于JDBC,写入消息时会将消息写入到日志文件,正是由于顺序追加写,性能很高。而且创建了消息主键索引,并提供了缓存机制,进一步的提升了性能。每个日志文件大小都有限制(默认32M,可以配置)。

当文件大小超过限制,系统会新建立一个文件,当所有的消息都消费完成,系统会删除这个文件或者归档;

AMQ的主要缺点是回味每一个Destination创建一个索引,如果使用了大量的queue,索引文件会非常耗磁盘空间。

由于索引巨大,一旦Broker奔溃,恢复时重建索引会变得非常缓慢;

正是由于这些缺点,AMQ已经不再推荐使用。尽管AMQ的性能高于KaHaDB。

(2)KahaDB

KahaDB是从ActiveMQ5.4开始的默认持久化车辆。KahaDB是一个文件性数据库。是使用内存+文件的形式来保证数据的持久化的。KahaDB的文件也可以限制大小。

KahaDB的配置如下:

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

这样数据会自动同步到KahaDB目录下。KahaDB日志文件存储的路径:%activemq的安装目录%/data/kahadb 

其中:

db-*.log,该文件是保存消息内容的文件;

db.data,该文件是保存消息的索引文件,本质上是B-Tree的实现,使用B-Tree作为索引指向db-*.log里面存储的消息;

db.redo,该文件是当消息服务器宕机后,用来恢复消息的文件;

lock文件,文件表示当前获得KahaDB读写权限的broker。

KahaDB的特性:

1)消息使用一个事务日志和仅仅使用一个索引文件来存储它所有的地址;

2)消息以B-Tree结构存储,可以快速更新;

3)完全支持JMS事务;

4)支持多种恢复机制;

(3)JDBC

ActiveMQ使用数据库作为持久化,不限定具体的数据库,可以使用任意的数据库。下面以mysql为例。

1)首先打开activemq.xml配置文件,首先定义mysql的数据源mysql-ds,然后在<persistenceAdapter>标签中配置jdbcPersistenceAdapter并且引用刚才定义的数据源mysql-ds。

 <broker brokerName="test-broker" persistent="true" xmlns="http://activemq.apache.org/schema/core">
     <persistenceAdapter>
         <jdbcPersistenceAdapter dataSource="#mysql-ds" createTabelsOnStartUp="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://127.0.0.1/activemq?relaxAutoCommit=true" />
     <property name="username" value="root" />
     <property name="password" value="123456" />
     <property name="maxActive" value="200" />
     <property name="poolPreparedStatements" value="true" />
 </bean>

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

2)加mysql数据库的驱动jar包到activwmq/lib的文件夹下,注意:若使用第三方连接池或是连接器(例如c3p0、druid),应同时将其jar包添加到lib文件夹下

3)重启activemq。会自动生成如下3张表:

activemq_msgs用于存储消息,Queue和Topic都存储在这个表中;

activemq_acks用于存储订阅关系。如果是持久化Topic,订阅者和服务器的订阅关系在这个表保存;

activemq_lock表在集群环境下才有用,只有一个Broker可以获取消息,称为Master Broker,其他的只能作为备份等待Master Broker不可用,才可能成为下一个Master Broker。这个表用于记录哪个Broker是当前的Master Broker。

使用场景:

只有在消息必须保证有效,且绝对不能丢失的时候。使用JDBC存储策略

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章