ActiveMQ--消息的可靠性

持久性(PERSISTENT)

  • messageProducer.setDeliverMode(DeliverMode.NON_PERSISTENT); 非持久化:当服务器宕机,消息不存在
  • messgageProducer.setDeliveryMode(DeliveryMode.PERSISTENT); 持久化:当服务器宕机,消息依然存在。

队列(queue)的持久化:

队列的默认为持久化模式,此模式保证这些消息只被传送一次和成功使用一次。对于这些消息,可靠性是优先考虑的因素。

可靠性的另一个重要方面是确保持久性消息传送到目标后,消息服务在向消费者传送它们之前不会丢失这些消息。

主题(topic)的持久化:
消费方代码:

package pres.zhang.persistent;

import org.apache.activemq.ActiveMQConnectionFactory;

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

public class Topic_Consumer {
    public static final String ACTIVEMQ_URL = "tcp://localhost:61616";
    public static final String TOPIC_NAME = "topic_acton";

    public static void main(String[] args) throws JMSException, IOException {
        //1.创建连接工厂,按照给定的url地址,采用默认用户名和密码
        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
        //2.通过连接工厂,获得连接connection,并启动访问
        Connection connection = activeMQConnectionFactory.createConnection();
        //connection.start();

        //设置订阅用户
        connection.setClientID("test");

        //3.创建回话session
        //两个参数 1.事务  2.签收
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //4.创建目的地(具体是队列还是主题topic)
        Topic topic = session.createTopic(TOPIC_NAME);

        //创建持久化的订阅 参数:1.主题 2.备注
        TopicSubscriber topicSubscriber = session.createDurableSubscriber(topic, "remard");

        //发布订阅
        connection.start();
        Message message = topicSubscriber.receive();

        while (null != message){
            TextMessage textMessage = (TextMessage) message;
            System.out.println("收到的持久化topic:" + ((TextMessage) message).getText());
            //继续监听
            message = topicSubscriber.receive(1000L);
        }

        session.close();
        connection.close();
    }
}

生产方代码:

package pres.zhang.persistent;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

public class Topic_Produce {
    public static final String ACTIVEMQ_URL = "tcp://localhost:61616";
    public static final String TOPIC_NAME = "topic_acton";

    public static void main(String[] args) throws JMSException {
        //1.创建连接工厂,按照给定的url地址,采用默认用户名和密码
        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
        //2.通过连接工厂,获得连接connection,并启动访问
        Connection connection = activeMQConnectionFactory.createConnection();
        //connection.start();

        //3.创建回话session
        //两个参数 1.事务  2.签收
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //4.创建目的地(具体是队列还是主题topic)
        Topic topic = session.createTopic(TOPIC_NAME);
        //创建消息的生产者
        MessageProducer messageProducer = session.createProducer(topic);
        //通过使用messageProducer生产3条消息发送到MQ的队列里面

        //设置持久化主题
        messageProducer.setDeliveryMode(DeliveryMode.PERSISTENT);
        //因为设置持久化主题,所以connect.start()在这里调用
        connection.start();
        for (int i = 0; i < 3; i++) {
            //7.创建消息
            TextMessage textMessage = session.createTextMessage("TOPIC_NAME---" + i);//可以理解为字符串
            //8.通过messageProducer发送给MQ
            messageProducer.send(textMessage);
        }
        //9.关闭资源
        messageProducer.close();
        session.close();
        connection.close();;
        System.out.println("消息发布到TOPIC完成!");
    }
}

测试:先运行消费方,进行主题订阅:
在这里插入图片描述
在这里插入图片描述

显示有一个活跃的订阅者,因为并没有消息给消费者消费,所以程序一直在监听。我们关闭程序,变化如下:
在这里插入图片描述
因为我们终止的程序,所以显示到了offline栏,但是我们已经成功订阅。

现在运行消息的生产者:
在这里插入图片描述
在这里插入图片描述

消息发送成功。我们再次运行消费者:
控制台打印:

收到的持久化topic:TOPIC_NAME---0
收到的持久化topic:TOPIC_NAME---1
收到的持久化topic:TOPIC_NAME---2

在这里插入图片描述
在这里插入图片描述

成功接收到消息,因为我们已经订阅了该主题。

扫描二维码关注公众号,回复: 8738723 查看本文章

总结:

  1. 一定要先运行一次消费者,等于向MQ注册,类似我们订阅了这个主题。
  2. 然后再运行生产者发送消息
  3. 此时,无论消费者是否在线,都会接收到,不在线的话,下次连接的时候,会把没有收过的消息都接收下来。
发布了636 篇原创文章 · 获赞 1867 · 访问量 23万+

猜你喜欢

转载自blog.csdn.net/cold___play/article/details/104056112