activemq - 断线恢复
什么是消息持久化?
业务需求:如果有人重启队列,队列里的东西要留着,不能给清空了。
在 activemq 中, 通过设置 DeliveryMode 来控制消息是否持久化。
- DeliveryMode.NON_PERSISTENT:不持久化;
- DeliveryMode.PERSISTENT:持久化;
- queue 默认是持久化的;topic 默认是不持久化的;
topic 模式下,如何保留断线期间的消息
业务需求:client 断线期间,需要补发断线期间的消息。
queue 是一对一的,如果 client 断线,断线期间的消息,会在重启之后发送;
topic 是一对多的,如果 client 断线,断线期间的消息,会被直接丢弃。
那问题来了,既要又要,又当如何?既要一对多,断线期间的消息又必须保留。
这时候要用到特殊的 TopicSubscriber,代码参考后续案例。
案例
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
/**
* 测试消息队列
*
* @author Mr.css
* @version 2024-10-12 11:09
*/
public class ActiveMQSender {
private static final String USERNAME = "admin";
private static final String PASSWORD = "admin";
private static final String BROKER_URL = "tcp://localhost:61616";
private static final String TOPIC_NAME = "MyQueue";
public static void main(String[] args) throws Exception {
// 连接池
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(USERNAME, PASSWORD, BROKER_URL);
// 连接
Connection connection = factory.createConnection();
connection.start();
// 会话 - 自动确认 ACK
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createTopic(TOPIC_NAME);
// 消息生产者 - 非持久化消息
MessageProducer producer = session.createProducer(destination);
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
TextMessage message = session.createTextMessage("Hello ActiveMQ!");
producer.send(message);
System.out.println("Sent message: " + message.getText());
session.close();
connection.close();
}
}
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
/**
* 测试消息队列
*
* @author Mr.css
* @version 2024-10-12 11:09
*/
public class ActiveMQReceiver {
private static final String USERNAME = "admin";
private static final String PASSWORD = "admin";
private static final String BROKER_URL = "tcp://localhost:61616";
private static final String TOPIC_NAME = "MyQueue";
public static void main(String[] args) throws Exception {
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(USERNAME, PASSWORD, BROKER_URL);
// 连接
Connection connection = factory.createConnection();
// 设置客户端 ID,向 MQ 服务器注册自己的名称
connection.setClientID("client_a");
// 会话 - 自动确认
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Topic topic = session.createTopic(TOPIC_NAME);
// 创建一个 topic 订阅者对象
TopicSubscriber topicSubscriber = session.createDurableSubscriber(topic, "playWithUs");
connection.start();
while (true) {
// receive() 函数如果不带参数,则表示持续侦听消息
TextMessage message = (TextMessage) topicSubscriber.receive();
if (message != null) {
System.out.println("Received message: " + message.getText());
} else {
// 如果是持续接受消息,这里执行不到
break;
}
}
session.close();
connection.close();
}
}
疯狂的妞妞 :每一天,做什么都好,不要什么都不做!