ActiveMQ消息持久化(主题)
在非持久化的主题模式例子中,假如消费者与activemq 服务器断开连接,那么就无法继续接收生产者发布的消息,即使断开的消费者再重新连接也无法获取到生产者上次发布的消息,生活中有很多类似的例子,例如当别人给自己发送短信时,手机无信号或处于关机状态,此时短信并不会丢失,等到开机或重新连接网络后仍然可以接收到短信
在主题模式下实现消息持久化
生产者:
package service.topic.persistent;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
public class PersistentTopicProducer {
/**
* ActiveMq服务器地址
* 支持的协议参见官网 http://activemq.apache.org/configuring-transports
* TCP协议使用文档 http://activemq.apache.org/tcp-transport-reference
*/
public static final String DEFAULT_BROKER_URL = "tcp://192.168.136.135:61616";
public static final String USER_NAME = "admin";
public static final String PWD = "admin";
public static final String TOPIC_NAME = "test.persistent.topic";
public void work() {
try {
// 1. Create a ConnectionFactory
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(USER_NAME, PWD, DEFAULT_BROKER_URL);
// 2. Create a Connection
Connection connection = connectionFactory.createConnection();
// 3. Create a Session
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// 4.Create the destination (Topic or Queue)
Destination destination = session.createTopic(TOPIC_NAME);
// 5. Create a MessageProducer from the Session to the Topic or Queue 创建消息生产者
MessageProducer producer = session.createProducer(destination);
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
connection.start();
// 6. Create a messages 创建消息
String text = System.currentTimeMillis() + "Hello world! From: " + Thread.currentThread().getName();
TextMessage message = session.createTextMessage(text);
// Tell the producer to send the message 生产者发送消息
System.out.println("Sent message: " + text);
producer.send(message);
// Clean up
session.close();
connection.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new PersistentTopicProducer().work();
}
}
消费者:
package service.topic.persistent;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.Connection;
import javax.jms.ExceptionListener;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.jms.TopicSubscriber;
public class PersistentTopicConsumer {
/**
* ActiveMq服务器地址
* 支持的协议参见官网 http://activemq.apache.org/configuring-transports
* TCP协议使用文档 http://activemq.apache.org/tcp-transport-reference
*/
public static final String DEFAULT_BROKER_URL = "tcp://192.168.136.135:61616";
public static final String USER_NAME = "admin";
public static final String PWD = "admin";
public static final String TOPIC_NAME = "test.persistent.topic";
private String clientId;
public PersistentTopicConsumer() {
}
public PersistentTopicConsumer(String clientId) {
this.clientId = clientId;
}
public static void main(String[] args) {
new PersistentTopicConsumer("zhangsan").work();
}
public void work() {
Connection connection = null;
Session session = null;
TopicSubscriber topicSubscriber = null;
try {
// 1. Create a ConnectionFactory
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(USER_NAME, PWD, DEFAULT_BROKER_URL);
// 2. Create a Connection
connection = connectionFactory.createConnection();
//设置 clientId,必须唯一
connection.setClientID(this.clientId);
connection.setExceptionListener(new ExceptionListener() {
public void onException(JMSException e) {
System.out.println("JMS Exception occured. Shutting down client.");
}
});
// 3. Create a Session
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// 4.Create the destination (Topic or Queue)
Topic destination = session.createTopic(TOPIC_NAME);
// 5.创建持久化订阅者
topicSubscriber = session.createDurableSubscriber(destination, "");
connection.start();
final String thisClientId = this.clientId;
// 6. Wait for a message
topicSubscriber.setMessageListener(new MessageListener() {
public void onMessage(Message message) {
if (message instanceof TextMessage) {
TextMessage textMessage = (TextMessage) message;
String text = null;
try {
text = textMessage.getText();
} catch (JMSException e) {
e.printStackTrace();
}
System.out.println(thisClientId + " Received: " + text);
} else {
System.out.println(thisClientId + " Received: " + message);
}
}
});
// 阻塞线程,使消息消费完后才关闭连接
System.in.read();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (topicSubscriber != null) {
topicSubscriber.close();
}
if (session != null) {
session.close();
}
if (connection != null) {
connection.close();
}
} catch (JMSException e) {
e.printStackTrace();
}
}
}
}
测试:
① 启动 service.topic.persistent.PersistentTopicConsumer
访问管理页面可见持久化主题订阅者一栏已经有了刚刚启动的客户端信息
②启动生产者service.topic.persistent.PersistentTopicProducer
订阅者正常接收消息
③关闭订阅者
④生产者再次生产消息
⑤再次启动断开的订阅者
消息成功接收