重启activemq会自动生成如下3张表。如果没有自动生成需要我们手动执行SQL。我个人建议要自动生成,我在操作过程中查看日志文件发现了不少问题,最终解决了这些问题后是能够自动生成的。如果不能自动生成说明你的操作有问题。表字段说明如下
ACTIVEMQ_MSGS 消息数据表
ACTIVEMQ_ACKS数据表
ACTIVEMQ_LOCK数据表:表ACTIVEMQ_LOCK在集群环境下才有用,只有一个Broker可以获取消息,称为Master Broker,其他的只能作为备份等待Master Broker不可用,才可能成为下一个Master Broker。这个表用于记录哪个Broker是当前的Master Broker 。
Queue验证和数据表变化
在点对点类型中,当DeliveryMode设置为NON_PERSISTENCE时,消息被保存在内存中。当DeliveryMode设置为PERSISTENCE时,消息保存在broker的相应的文件或者数据库中。而且点对点类型中消息一旦被Consumer消费,就从数据中删除,消费前的消息会被存放到数据库 上面的消息被消费后被MQ自动删除。
Queue非持久化模式:不会将消息持久化到数据库
Queue持久化模式:会将消息持久化到数据库,但是消息被消费者消费后会自动删除持久化数据。
我们使用queue持久化模式发布3条消息后,发现ACTIVEMQ_MSGS数据表多了3条数据。
启动消费者消费了所有的消息后,发现数据表的数据消失了。
Topic验证和说明
设置了持久订阅数据库里面会保存订阅者的信息
ACTIVEMQ_ACKS表中的LAST_ACKED_ID记录了CLIENT_ID最后签收的一条消息,而LAST_ACKED_ID和ACTIVEMQ_MSGS的ID字段是外键关联关系,这样就可以实现Topic的消息保存到ACTIVEMQ_MSGS表内的同时还能根据ACTIVEMQ_ACKS表中的持久订阅者查到该订阅者上次收到的最后一条消息是什么。值得注意的是Topic内的消息是不会被删除的,而Queue的消息在被删除后会在数据库中被删除,如果需要保存Queue,应该使用其他方案解决。
我们启动主题持久化,生产者发布3个数据,ACTIVEMQ_MSGS数据表新增3条数据,消费者消费所有的数据后,ACTIVEMQ_MSGS数据表的数据并没有消失。持久化topic的消息不管是否被消费,是否有消费者,产生的数据永远都存在,且只存储一条。这个是要注意的,持久化的topic大量数据后可能导致性能下降。这里就像公总号一样,消费者消费完后,消息还会保留。
总结
如果是Queue,在没有消费者消费的情况下会将消息保存到activemq_msgs表中,只要有任意一个消费者消费了,就会删除消费过的消息。
如果是Topic,一般是先启动消费订阅者然后再生产的情况下会将持久订阅者永久保存到qctivemq_acks,而消息则永久保存在activemq_msgs,在acks表中的订阅者有一个last_ack_id对应了activemq_msgs中的id字段,这样就知道订阅者最后收到的消息是哪一条。
常见坑
在配置关系型数据库作为ActiveMQ的持久化存储方案时,有许多坑。
数据库jar包:注意对应版本的数据库jar或者你自己使用的非自带的数据库连接池jar包
createTablesOnStartup属性:该属性默认为true,每次启动activemq都会自动创建表,在第一次启动后应改为false避免不必要的损失。
下划线:报错"java.lang.IllegalStateException: LifecycleProcessor not initialized"。确认计算机主机名名称没有下划线
8.5 JDBC Message Store with ActiveMQ Journal理解
这种方式克服了JDBC Store的不足,JDBC每次消息过来都需要去写库读库。ActiveMQ Journal,使用高速缓存写入技术大大提高了性能。当消费者的速度能够及时跟上生产者消息的生产速度时,journal文件能够大大减少需要写入到DB中的消息。
举个例子:生产者生产了1000条消息,这1000条消息会保存到journal文件,如果消费者的消费速度很快的情况下,在journal文件还没有同步到DB之前,消费者已经消费了90%的以上消息,那么这个时候只需要同步剩余的10%的消息到DB。如果消费者的速度很慢,这个时候journal文件可以使消息以批量方式写到DB。