1. 持久化方式介绍
前面我们也简单提到了activemq提供的插件式的消息存储,在这里再提一下,主要有以下几种方式:

AMQ消息存储-基于文件的存储方式,是activemq开始的版本默认的消息存储方式;
KahaDB消息存储-提供了容量的提升和恢复能力,是现在的默认存储方式;
JDBC消息存储-消息基于JDBC存储的;
Memory消息存储-基于内存的消息存储,由于内存不属于持久化范畴,而且如果使用内存队列,可以考虑使用更合适的产品,如ZeroMQ。所以内存存储不在讨论范围内。
上面几种消息存储方式对于消息存储的逻辑来说并没有什么区别,只是在性能以及存储方式上来说有所不同。但是对于消息发送的方式来说,p2p和Pub/Sub两种类型的消息他们的持久化方式却是不同的:

对于点对点的消息一旦消费者完成消费这条消息将从broker上删除;对于发布订阅类型的消息,即使所有的订阅者都完成了消费,Broker也不一定会马上删除无用消息,而是保留推送历史,之后会异步清除无用消息。而每个订阅者消费到了哪条消息的offset会记录在Broker,以免下次重复消费。因为消息是顺序消费,先进先出,所以只需要记录上次消息消费到哪里就可以了。

因为AMQ现在已经被不再使用被KahaDB所替代,所以我们就讲KahaDB,JDBC消息存储在许多对可靠性要求高而对性能要求低一些的大公司还是经常使用的,下面我们就这两种持久化方式的使用做一节专题。

2. Kahadb
说到Kahadb之前我们还是得提到他的前身AMQ,AMQ是一种文件存储形式,他具有写入速度快和容易恢复的特点,消息存储在一个个的文件里,文件默认大小为32M,超过这个大小的消息将会存入下一个文件。当一个文件中的消息已经全部消费,那么这个文件将被标志我可删除,在下一个清除阶段这个文件将被删除。

如果需要使用持久化,则需要在前文中的配置文件applicationContext-ActiveMQ.xml中增加如下配置:

<persistenceAdapter>
<kahaDB directory="activemq-data"journalMaxFileLength="32mb"/>
</persistenceAdapter>
KahaDB的属性件如下

属性名称 属性值 描述
directory activemq-data 消息文件和日志的存储目录
indexWriteBatchSize 1000 一批索引的大小,当要更新的索引量到达这个值时,更新到消息文件中
indexCacheSize 1000 内存中,索引的页大小
enableIndexWriteAsync false 索引是否异步写到消息文件中
journalMaxFileLength 32mb 一个消息文件的大小
enableJournalDiskSyncs true 是否讲非事务的消息同步写入到磁盘
cleanupInterval 30000 清除操作周期,单位ms
checkpointInterval 5000 索引写入到消息文件的周期,单位ms
ignoreMissingJournalfiles false 忽略丢失的消息文件,false,当丢失了消息文件,启动异常
checkForCorruptJournalFiles false 检查消息文件是否损坏,true,检查发现损坏会尝试修复
checksumJournalFiles false 产生一个checksum,以便能够检测journal文件是否损坏。
5.4版本之后有效的属性:
archiveDataLogs false 当为true时,归档的消息文件被移到directoryArchive,而不是直接删除
directoryArchive null 存储被归档的消息文件目录
databaseLockedWaitDelay 10000 在使用负载时,等待获得文件锁的延迟时间,单位ms
maxAsyncJobs 10000 同个生产者产生等待写入的异步消息最大量
concurrentStoreAndDispatchTopics false 当写入消息的时候,是否转发主题消息
concurrentStoreAndDispatchQueues true 当写入消息的时候,是否转发队列消息
5.6版本之后有效的属性:
archiveCorruptedIndex false 是否归档错误的索引

  由于在ActiveMQ V5.4+的版本中,KahaDB是默认的持久化存储方案。所以即使你不配置任何的KahaDB参数信息,ActiveMQ也会启动KahaDB。这种情况下,KahaDB文件所在位置是你的ActiveMQ安装路径下的/data/broker.Name/KahaDB子目录。其中broker.Name/KahaDB子目录。其中{broker.Name}代表这个ActiveMQ服务节点的名称。下面我把刚启动服务并发送了消息之后的activemq安装目录打开给大家看看:

正式的生产环境还是建议在主配置文件中明确设置KahaDB的工作参数:

<broker xmlns="http://activemq.apache.org/schema/core" brokerName="broker" persistent="true" useShutdownHook="false">
...
<persistenceAdapter>
<kahaDB directory="activemq-data"
journalMaxFileLength="32mb"
concurrentStoreAndDispatchQueues="false"
concurrentStoreAndDispatchTopics="false"
/>
</persistenceAdapter>
</broker>
3.持久化到数据库

步骤1:需要将mysql的驱动包放置到ActiveMQ的lib目录下(mysql-connector-java-5.1.30.jar)

步骤2:修改activeMQ的配置文件如下:两处地方

<persistenceAdapter>
<!--<kahaDB directory="${activemq.base}/data/kahadb"/>-->
<jdbcPersistenceAdapter dataDirectory="${activemq.base}/data" dataSource="#mysql-ds" useDatabaseLock="false" createTablesOnStartup="false"/>
</persistenceAdapter>

在配置文件中的broker节点外( </broker>下方)增加:

<!-- MySql DataSource Sample Setup -->
<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://localhost:3306/activemqdb?relaxAutoCommit=true"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
<property name="poolPreparedStatements" value="true"/>
</bean> <!-- Oracle DataSource Sample Setup
<bean id="db2-ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.ibm.db2.jcc.DB2Driver"/>
<property name="url" value="jdbc:db2://hndb02.bf.ctc.com:50002/activemq"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
<property name="maxActive" value="200"/>
<property name="poolPreparedStatements" value="true"/>
</bean> -->

从配置中可以看出数据库的名称是activemq,你需要手动在MySql中增加这个库,这个数据库要先存在。然后重新启动activeMQ(启动建议启动activemq.bat方式,报错信息可以在命令行看到),会发现activemq多了三张表:从配置中可以看出数据库的名称是activemq,需要手动在MySql中建立这个数据库。(一下三张图是我在别人那里看到,画的很详细,特此感谢博主:技术宅home)

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

activemq_lock:在集群环境中才有用,只有一个Broker可以获得消息,称为Master Broker

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

感兴趣的可以去验证一下,启动一个点对点模式的生产者,不要启动消费者,否则会被马上接收,来不及持久化。会发现数据库消息表中有一条消息了

然后启动消费者,会发现表中的数据就会删除了。

持久化表中最后没有被的数据一般是死亡队列中消息和在消息队列中等待被消费确认的消息。

学习ActiveMQ(八):activemq消息的持久化的更多相关文章

  1. JMS学习(五)--ActiveMQ中的消息的持久化和非持久化 以及 持久订阅者 和 非持久订阅者之间的区别与联系

    一,消息的持久化和非持久化 ①DeliveryMode 这是传输模式.ActiveMQ支持两种传输模式:持久传输和非持久传输(persistent and non-persistent deliver ...

  2. SpringCloud学习(八)消息总线(Spring Cloud Bus)(Finchley版本)

    Spring Cloud Bus 将分布式的节点用轻量的消息代理连接起来.它可以用于广播配置文件的更改或者服务之间的通讯,也可以用于监控.本文要讲述的是用Spring Cloud Bus实现通知微服务 ...

  3. JMS学习九(ActiveMQ的消息持久化到Mysql数据库)

    1.将连接Mysql数据库的jar文件,放到ActiveMQ的lib目录下 2.修改ActiveMQ的conf目录下的active.xml文件,修改数据持久化的方式 2.1  修改原来的kshadb的 ...

  4. JMS学习三(ActiveMQ消息的可靠性)

    下面我们来学习一下消息接受确认和发送持久化消息.消息的过期.消息的选择器和消息的优先级. 一.消息接收确认 1.jms消息只有在被确认之后才认为成功消费了这条消息.消息的成功消费通常包括三个步骤:(1 ...

  5. JMS学习六(ActiveMQ消息传送模型)

    ActiveMQ 支持两种截然不同的消息传送模型:PTP(即点对点模型)和Pub/Sub(即发布 /订阅模型),分别称作:PTP Domain 和Pub/Sub Domain. 一.PTP消息传送模型 ...

  6. ActiveMQ(3)---ActiveMQ原理分析之消息持久化

    持久化消息和非持久化消息的存储原理 正常情况下,非持久化消息是存储在内存中的,持久化消息是存储在文件中的.能够存储的最大消息数据在${ActiveMQ_HOME}/conf/activemq.xml文 ...

  7. ActiveMQ消息的持久化策略

    持久化消息和非持久化消息的存储原理: 正常情况下,非持久化消息是存储在内存中的,持久化消息是存储在文件中的.能够存储的最大消息数据在${ActiveMQ_HOME}/conf/activemq.xml ...

  8. JMS服务器ActiveMQ的初体验并持久化消息到MySQL数据库中

    JMS服务器ActiveMQ的初体验并持久化消息到MySQL数据库中 一.JMS的理解JMS(Java Message Service)是jcp组织02-03年定义了jsr914规范(http://j ...

  9. 消息中间件-activemq实战之消息持久化(六)

    对于activemq消息的持久化我们在第二节的时候就简单介绍过,今天我们详细的来分析一下activemq的持久化过程以及持久化插件.在生产环境中为确保消息的可靠性,我们肯定的面临持久化消息的问题,今天 ...

  10. AMQP学习 & RabbitMQ 与 ActiveMQ、ZeroMQ以及Kafka的比较

    之前写了一篇文章关于Active以及消息队列推拉模式的文章,可以参考:link 关于 Active 与 RabbitMQ以及其他的比较,有如下记录: 这篇文章 link 提到: 基本介绍RabbitM ...

随机推荐

  1. js设置document.domain实现跨域

    document.domain 只能实现跨子域的问题 如:xxx.com/a.html 和aaa.xxx.com/b.html 或:bbb,xxx.com/c.html 和ccc.xxx.com/d. ...

  2. 51nod--1069 Nim 游戏(博弈论)

    题目: 有N堆石子.A B两个人轮流拿,A先拿.每次只能从一堆中取若干个,可将一堆全取走,但不可不取,拿到最后1颗石子的人获胜.假设A B都非常聪明,拿石子的过程中不会出现失误.给出N及每堆石子的数量 ...

  3. java的官网下载(如有不懂,可以去我发的视频网站,那里面有详细过程)

    https://www.oracle.com/technetwork/java/javase/downloads/java-archive-javase9-3934878.html java 9的下载 ...

  4. HTTP Status 500 - java.lang.reflect.InvocationTargetException

    type Exception report message java.lang.reflect.InvocationTargetException description The server enc ...

  5. 在vue里添加好看的lottie动画 (^_^)

    为什么用lottie ★~★ 1.能让你的程序不那么单调 2.能让一些有审美强迫症的同学好受一点 3.网上有丰富的资源 点我进入lottie资源网站 引入lottie库 (>.<) 在vu ...

  6. Kafka生产者发送消息的三种方式

    Kafka是一种分布式的基于发布/订阅的消息系统,它的高吞吐量.灵活的offset是其它消息系统所没有的. Kafka发送消息主要有三种方式: 1.发送并忘记 2.同步发送 3.异步发送+回调函数 下 ...

  7. Linux下IPC中的信号量PV操作

    代码如下所示,两边对照查看程序!(左图为先运行进程 右图为后运行进程)    运行的效果就是:当左边的进程检测到EOF,释放资源V操作之后,右边的进程会迅速的执行对应的printf的操作! 所有代码文 ...

  8. Maya cmds pymel scriptJob() 和 undoInfo() 在回调中撤销(undo)

    Maya cmds pymel scriptJob() 和 undoInfo() 在回调中撤销(undo) def myEventFun(): cmds.undoInfo(stateWithoutFl ...

  9. C - 树的统计Count - 树链剖分

    思路 :树剖模板,线段树维护即可. #include<bits/stdc++.h> using namespace std; #define MID int m = (l+r)/2 #de ...

  10. 命令行编译C程序

    1 准备工作 下载mingw-get-setup.exe并且安装  参考 http://www.jb51.net/softjc/159871.html 环境变量更新: PATH .;C:\MinGW\ ...