ActiveMQ消息持久化
和前面我们说的持久,事物,签收不同的,前面的都是局限在同一台机器上,如果本机器坏了,那全部的消息也都丢失了
和Redis的持久化其实是一个概念,当我的主机宕机了也能将消息持久到硬盘或者其他上面(物理备份),方便恢复
官网详情:http://activemq.apache.org/persistence
ActiveMQ的消息持久化机制:
JDBC,AMQ,KahaDB,LevelDB,几种的存储逻辑都是一致的,将消息发出后,消息中心首先将消息存储到本地数据文件,内存数据库或者远程数据库,再试图将消息发送给接收者,成功则将消息从存储中删除,失败则继续尝试发送
消息中心启动后首先要检查指定的存储位置,若发现没有成功发送的消息,则需要把消息发送出去
AMQ:
AMQ是一种以文件形式存储的机制,现在淘汰了,是5.3以前的
KahaDB:
以日志形式记录消息,5.4以后默认就是KahaDB
配置文件activemq.xml里默认KahaDB
官网详情:http://activemq.apache.org/persistence.html
kahaDB存储在data目录
kahadb目录:
KahaDB消息存储使用一个事物日志(db.log)和一个索引文件(db.data)来存储它的所有地址,日志相当于书的文章,索引相当于目录
db-<number>.log用来存储消息,当此文件存储满了,又会产生一个新的文件,如第一个是db-1.log,当存储满了,又会产生一个db-2.log,类推,当不再有引用到数据库文件中的任何消息时,文件会被删除或者归档
db.data包含了持久化的BTree索引,索引了消息数据记录中的消息,它是消息的索引文件,本质时B树
db.rebo:用来进行消息恢复,如果KahaDB消息存储在强制退出后启动,用于恢复B树索引
lock:文件锁,就像mysql中的悲观锁,表示获得当前KahaDB读写操作的broker
LevelDB:
基于文件的存储,没有使用B树作为索引(了解),5.8后才出现
<persistenceAdapter> <levelDB directory="activemq-data"/> </persistenceAdapter>
JDBC消息存储:
同步消息到mysql
步骤:1.添加mysql驱动包到/activemq/lib下
2.jdbcPersistenceAdapter
配置,将其取代KahaDB
<persistenceAdapter> <jdbcPersistenceAdapter dataSource="#my-ds"/> </persistenceAdapter>
3.数据库连接池配置
<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://自己数据库/activemq?relaxAutoCommit=true"/> <property name="username" value="用户名"/> <property name="password" value="密码"/> <property name="poolPreparedStatements" value="true"/> </bean>
注:上面使用的时dbcp2连接池,所以不用引入其他jar包,因为时默认的,如果c3p0,或在druid等连接池,需要引入除了mysql驱动以外的jar包到lib下
4.建数据库和表
数据库名这里为activemq,如果配置没错,数据库连通的话,运行代码就会产生3张表,
ACTIVEMQ_MEGS
ACTIVEMQ_ACKS
ACTIVEMQ_LOCK
自动生成表是因为createTablesOnStartup设置为true,默认为true,
5.代码验证
当DeliveryMode设置为NON_PERSISTANCE时,消息被保存到内存中
设置为PERSISTANCE,消息保存到相应的文件或者数据库中
在队列模式中,消息一旦被消费后就从相应的文件或者数据库删除
在springboot工程中我投放了五条消息
上述是队列模式的持久化
此时消息还没有被消费掉,所以持久化到了数据库
然后启动消费者消费消息
此时消息被消费后,就从数据库中删除,为空
以上是队列模式的持久化
官方推荐使用下面这个.效率高
<persistenceFactory> <journalPersistenceAdapterFactory journalLogFiles="5" dataDirectory="${basedir}/target" /> <!-- To use a different dataSource, use the following syntax : --> <!-- <journalPersistenceAdapterFactory journalLogFiles="5" dataDirectory="${basedir}/activemq-data" dataSource="#mysql-ds"/> --> </persistenceFactory>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端