我们知道Topic在运行的时候,是先启动消费者,后启动生产者的。

对于Topic的持久化,我们做下面的操作,启动consumer,设置messageProducer是DeliveryMode.PERSISTENT,启动producer,此时消费者可以拿到消息。我们进入管理页面,点击Subscribers标签,可以看到下图。

ActiveMQ笔记27-持久化topic_java

在Active Durable Topic Subscribers里可以看到有一个消费者的信息,此时,我们将这个消费者线程关闭,再来看看,可以看到这个消费者跑到了Offline Durable Topic Subscribers里面,如下图所示。表明这个消费者离线了,但是依旧保持订阅关系。

ActiveMQ笔记27-持久化topic_持久化_02

下面做这么一个试验,此时消费者已经离线,我们先启动生产者,后启动消费者,试想,此时,消费者还能接收到刚才生产者发送的消息吗?

答案是:可以的。此时再刷新管理后台,可以看到刚才那个Offline的Subscribers跑到了Active里面。

此时,我们可以想象一个场景,我订阅了某公众号,后来我手机没电关机了,当我意识到后,充电再开机,我依旧能收到公众号推送给我的消息,这里的持久化,可以认为,我和公众号的联系被持久化了,所以我上线后可以及时收到消息。

话不多说,上代码,需要根据前面做一定的修改。

package com.wsy.activemq.queue;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

public class JmsProducer_Topic_Presistent {
public static final String ACTIVEMQ_URL = "tcp://192.168.0.123:61616";
public static final String TOPIC_NAME = "topic01";

public static void main(String[] args) throws JMSException {
// 创建连接工厂,按照给定的url地址采用默认的用户名和密码
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
// 通过连接工厂,获取Connection
Connection connection = activeMQConnectionFactory.createConnection();
// 创建Session
// 有两个参数,第一个是事务,第二个是签收,后面详细介绍
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// 创建目的地(目的地有两个子接口,分别是Queue和Topic)
Topic topic = session.createTopic(TOPIC_NAME);
// 创建消息生产者,生产的消息放到topic中
MessageProducer messageProducer = session.createProducer(topic);
// 设置持久化主题并启动
messageProducer.setDeliveryMode(DeliveryMode.PERSISTENT);
connection.start();
// 使用messageProducer生产消息发送到主题中
for (int i = 0; i < 3; i++) {
// 创建一条消息,可以理解成字符串
TextMessage textMessage = session.createTextMessage("message-" + i);
// 通过messageProducer发送消息给mq
messageProducer.send(textMessage);
}
// 按照资源打开的相反顺序关闭资源
messageProducer.close();
session.close();
connection.close();
}
}
package com.wsy.activemq.queue;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

public class JmsConsumer_Topic_Presistent {
public static final String ACTIVEMQ_URL = "tcp://192.168.0.123:61616";
public static final String TOPIC_NAME = "topic01";

public static void main(String[] args) throws JMSException {
// 创建连接工厂,按照给定的url地址采用默认的用户名和密码
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
// 通过连接工厂,获取Connection
Connection connection = activeMQConnectionFactory.createConnection();
// 设置ClientID
connection.setClientID("client1");
// 创建Session
// 有两个参数,第一个是事务,第二个是签收,后面详细介绍
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// 创建目的地(目的地有两个子接口,分别是Queue和Topic)
Topic topic = session.createTopic(TOPIC_NAME);
// 创建一个主题订阅者,指明订阅的主题,指明订阅者的标识
TopicSubscriber topicSubscriber = session.createDurableSubscriber(topic, "topicSubscriber1");
// 启动connection
connection.start();
// 接收消息
Message message = topicSubscriber.receive();
while (message != null) {
TextMessage textMessage = (TextMessage) message;
System.out.println("topicSubscriber接收到的消息:" + textMessage.getText());
message = topicSubscriber.receive();
}
session.close();
connection.close();
}
}