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();
    }
}


posted on 2024-11-04 09:09  疯狂的妞妞  阅读(8)  评论(0编辑  收藏  举报

导航