1、持久化:
①为什么持久化:
1、其实activeMQ本身是有保证数据可靠性的一些机制,例如自带的 producer.setDeliveryMode(DeliveryMode.PERSISTENT);设置持久化模式,或者开启事务及签收,都可以保证数据的可靠性。如果程序出现宕机重启都是没问题,数据不丢失的。
2、假如机器硬件出现问题,出现存储丢失呢?等等一些导致activeMQ不能访问,那我们可能需要考虑更加稳定可靠的机制处理对应问题。
②解决方案:
就是在activeMQ之外架设一个存储的区域,将MQ的消息存储到文件、硬盘、数据库等这个也称为activeMQ的持久化,这样数据将不会出现问题了。
官网 : http://activemq.apache.org/persistence
2、activeMQ持久化机制:
activeMQ官方文档
①有哪些机制及特点:
AMQ:5.3版本之前使用,是消息日志文件存储形式,写入快、易恢复,文件默认32M 在 ActiveMQ
KahaDB(默认):5.4版本之后默认持久化机制,基于AMQ的日志文件存储,比AMQ更快的恢复,更少的文件描述
LeavelDB:5.8 以后引入,也是基于文件的本地数据存储形式,但是比 KahaDB 更快,更快的原因是她不使用BTree 索引,而是使用本身自带的 LeavelDB 索引
题外话:为什么LeavelDB 更快,并且5.8 以后就支持,为什么还是默认 KahaDB 引擎,因为 activemq 官网本身没有定论,LeavelDB 之后又出了可复制的LeavelDB 比LeavelDB 更性能更优越,但需要基于 Zookeeper 所以这些官方还没有定论,任就使用 KahaDB
kahaDB文件组成
[root@centOS soft]# cd activeMQ_5.10.1/data/kahadb/
[root@centOS kahadb]# ll
<!-- 储存消息数据,到达32M,存到下一个db-数字.log文件中;当不被引用时将被删除或者归档 -->
-rw-r--r-- 1 root root 33030144 7月 7 12:55 db-2.log
<!--消息的索引,指向上面的具体数据,B树结构 -->
-rw-r--r-- 1 root root 18898944 7月 7 12:55 db.data
<!-- 当 KahaDB 消息存储在强制退出后启动,用于恢复 BTree 索引 -->
-rw-r--r-- 1 root root 18911224 7月 7 12:55 db.redo
<!--db.data那些页空闲的,文件具体内容是所有空闲页的id -->
-rw-r--r-- 1 root root 224 7月 7 12:55 db.free
<!-- 表示当前获取kahaDB读写权限的broker -->
-rw-r--r-- 1 root root 0 7月 6 20:27 lock
②常用的JDBC持久化:
①在activemq 的activeMQ_5.10.1/lib 目录下添加 jdbc 的jar 包 (mysql-connector-java-5.1.32.jar)
②修改配置 activeMQ_5.10.1/conf/activemq.xml 文件,默认 kahaDB
<persistenceAdapter>
<!-- <kahaDB directory="${activemq.data}/kahadb"/> -->
<!-- #获取id,相当于ref引用 ; createTablesOnStartup默认一启动就创建表-->
<jdbcPersistenceAdapter dataSource="#mysql-ds" createTablesOnStartup="true" />
</persistenceAdapter>
③ 修改配置文件 : activemq.xml 使其连接自己windows 上的数据库,并在本地创建名为activemq 的数据库
</broker>
<!-- 数据库设置-->
<bean id="mysql-ds" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://192.168.162.1:3306/activemq?relaxAutoCommit=true"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
<property name="poolPreparedStatements" value="true"/>
</bean>
./activeMQ console 使用验证activemq.xml是否配置正确 ,如果错误会出现报错
./activeMQ start/stop 开启和关闭
④ 让linux 上activemq 可以访问到 mysql ,之后产生消息。
ActiveMQ 启动后会自动在 mysql 的activemq 数据库下创建三张表:activemq_msgs 、activemq_acks、activemq_lock
mysql> desc activemq_msgs;
+------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+-------+
| ID | bigint(20) | NO | PRI | NULL | |
| CONTAINER | varchar(250) | YES | MUL | NULL | |消息目的地
| MSGID_PROD | varchar(250) | YES | MUL | NULL | |消息发送者的主键
| MSGID_SEQ | bigint(20) | YES | | NULL | |发送的顺序,组成jms的messageID
| EXPIRATION | bigint(20) | YES | MUL | NULL | |过期时间。0永不过期
| MSG | longblob | YES | | NULL | |消息本体的java序列化对象的二进制数据
| PRIORITY | bigint(20) | YES | MUL | NULL | |优先级
| XID | varchar(250) | YES | MUL | NULL | |
+------------+--------------+------+-----+---------+-------+
mysql> desc activemq_acks;
+---------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+-------+
| CONTAINER | varchar(250) | NO | PRI | NULL | |用于存储订阅关系
| SUB_DEST | varchar(250) | YES | | NULL | |
| CLIENT_ID | varchar(250) | NO | PRI | NULL | |
| SUB_NAME | varchar(250) | NO | PRI | NULL | |
| SELECTOR | varchar(250) | YES | | NULL | |
| LAST_ACKED_ID | bigint(20) | YES | | NULL | |
| PRIORITY | bigint(20) | NO | PRI | 5 | |
| XID | varchar(250) | YES | MUL | NULL | |
+---------------+--------------+------+-----+---------+-------+
mysql> desc activemq_lock;
+-------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+-------+
| ID | bigint(20) | NO | PRI | NULL | |
| TIME | bigint(20) | YES | | NULL | |
| BROKER_NAME | varchar(250) | YES | | NULL | |
+-------------+--------------+------+-----+---------+-------+
Queue:点对点producer.setDeliveryMode(DeliveryMode.PERSISTENT);生产者设置持久化模式,会将消息存储到mysql数据库和$AMQ_HOME\data\kr-store\data文件中,消费者消费消息后将会删除mysql数据库的消息数据。(而且设置非持久化模式将不会存储到数据库)。
topic:订阅模式设置持久化,消息发送到MQ,消费后数据库activemq_msgs、activemq_acks还有该数据
③JDBC Journal(缓存):
原理:queue生产者将消息发送activeMQ的时候,设置了持久化情况下,消息不会直接存储到mysql数据库,而是先进入缓存,如果在固定时间之内消费掉,将剩余的信息存入mysql,这样可以减轻数据库压力。
注意:activeMQ.xml配置时,需要注释AMQ或者kahaDB、JDBC、LeavelDB配置persistenceAdapter