ActiveMQ持久化

1. 消费者代码编写

package com.sxz.activemqconsumer;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;
import java.io.IOException;

/**
 * @author song.xinzhi
 * @Destination: TODO
 * @date: 2020/4/12
 */
public class TopicConsumerPersist {
    public static final String MQ_URL = "tcp://192.168.46.128:61616";

    /**
     *
     * @param args
     * @throws JMSException
     * @throws IOException
     */
    public static void main(String[] args) throws JMSException, IOException {
        //1. 创建一个工程连接类,以及session会话
        String userId = "songxinzhi01";
        System.out.println(userId + ":订阅主题begin....");
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(MQ_URL);
        Connection connection = connectionFactory.createConnection();
        connection.setClientID(userId);
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //2. 创建topic主题
        Topic topic = session.createTopic("persist-topic");
        //3. 创建持久化的订阅者
        TopicSubscriber topicSubscriber = session.createDurableSubscriber(topic, userId);
        connection.start();
        //4. 订阅者接收消息
        Message message = topicSubscriber.receive();
        while (null != message) {
            TextMessage textMessage = (TextMessage)message;
            System.out.println(userId + ":收到持久化topic:" + textMessage.getText());
            message = topicSubscriber.receive(5000L);
        }
        session.close();
        connection.close();
    }
}

启动消费者,观察MQ控制台,topic和Subscribers变化
在这里插入图片描述
Subscribers是刚才启动的订阅者在线
在这里插入图片描述
把消费者进程停掉观察Subscribers发现已经下线
在这里插入图片描述

2. 编写生产者代码

package com.sxz.activemqprovider;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

/**
 * @author song.xinzhi
 * @Destination: TODO
 * @date: 2020/4/12
 */
public class TopicProducerPersist {
    public static final String MQ_URL = "tcp://192.168.46.128:61616";
    public static void main(String[] args) throws JMSException, InterruptedException {
        //1、创建工厂连接对象以及连接对象
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(MQ_URL);
        Connection connection = connectionFactory.createConnection();
        //2、使用连接对象创建会话(session)对象
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //3、使用会话对象创建目标topic对象
        Topic topic = session.createTopic("persist-topic");
        //4、使用会话对象创建生产者对象
        MessageProducer producer = session.createProducer(topic);
        producer.setDeliveryMode(DeliveryMode.PERSISTENT);
        //5、开启连接
        connection.start();
        //6、使用会话对象创建一个消息对象,发送消息
        for (int i = 1; i <=8; i++) {
            Thread.sleep(5000L);
            TextMessage textMessage = session.createTextMessage("persist-topic_" + i);
            producer.send(textMessage);
        }
        //9、关闭资源
        producer.close();
        //10、关闭会话
        session.close();
        //11、关闭连接
        connection.close();
    }
}

上面消费者先在MQ上注册过了,后面又停掉了,我们发现订阅者从Active Durable Topic Subscribers列表移到了Offline Durable Topic Subscribers也就是从上线到下线的体现,此时消费者已经停掉,我们再启动生产者,发现此时生产者发出了5条消息等待消费者消费
在这里插入图片描述
这个时候我们再启动消费者
在这里插入图片描述
在这里插入图片描述
idea控制台打印出了消费了这5条消息,同时MQ的控制台也展示5条消息被消费了,这个测试说明,只要是消费者现在MQ上订阅过,就算消费者的客户端宕机了,重新启动后,还是会接收到生产者发布的消息 如果生产者先产生5条消息,消费者从来没有订阅过,如下先启动生产者,生产了5调消息在MQ服务器上,等待消费在这里插入图片描述
启动消费者
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
然而根据程序控制台和MQ控制台现象发现,5条消息并没有被生产者消费掉,也就是说明如果想消费生产者的消息之前必须要先订阅注册

3. ActiveMQ 持久化方案

持久化机制有JDBC,AMQ,KahaDB,LevelDB,可以参考官网:http://activemq.apache.org/persistence
5.3版本以后默认的是KahaDB
JDBC 存储

  1. 在安装的Mysql数据库中lib中添加依赖jar包
    在这里插入图片描述
  2. 修改activemq.xml配置文件
在persistenceAdapter加入如下配置<!--createTablesOnStartup    启动是否创建表  第一次为true 后续为false,第一次为true是为了创建表,之后的每次都不创建,使用第一次创建的表保存数据-->
<jdbcPersistenceAdapter dataSource="#activemq-db" createTablesOnStartup="true" />

在这里插入图片描述
3. 配置数据源,在beans节点中
在这里插入图片描述

<bean id="activemq-db"class="org.apache.commons.dbcp.BasicDataSource">          	
	<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>         
	<property name="url" value="jdbc:mysql://192.168.46.128:3306/activemq?serverTimezone=GMT%2B8"/>          
	<property name="username" value="root"/>          
	<property name="password" value="root"/>          
	<property name="maxActive" value="200"/>          
	<property name="poolPreparedStatements" value="true"/>    
</bean>
  1. 启动ActiveMQ,进程可以正常启动,可以看到数据库多了三张表
    在这里插入图片描述

activemq_acks: 用于存储订阅关系。如果是持久化Topic,订阅者和服务器的订阅关系在这个表保存,主要的数据库字段如下:
CONTAINER:消息的Destination
SUB_DEST:如果是使用Static集群,这个字段会有集群其他系统的信息CLIENT_ID:每个订阅者都必须有一个唯一的客户端ID用以区分SUB_NAME:订阅者名称
SELECTOR:选择器,可以选择只消费满足条件的消息。条件可以用自定义属性实现,可支持多属性AND和OR操作
LAST_ACKED_ID:记录消费过的消息的ID。
activemq_msgs: 用于存储消息,Queue和Topic都存储在这个表中:ID:自增的数据库主键
CONTAINER:消息的Destination
MSGID_PROD:消息发送者客户端的主键
MSG_SEQ:是发送消息的顺序,
MSGID_PROD+MSG_SEQ可以组成JMS的Message
IDEXPIRATION:消息的过期时间,存储的是从1970-01-01到现在的毫秒数MSG:消息本体的Java序列化对象的二进制数据
PRIORITY:优先级,从0-9,数值越大优先级越高
**activemq_lock:**在集群环境中才有用,只有一个Broker可以获得消息,称为Master Broker,其他的只能作为备份等待Master Broker不可用,才可能成为下一个Master Broker。这个表用于记录哪个Broker是当前的Master Broker。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值