如何保证消息的可靠性

JMS 可靠性:Persistent 持久性,事务, Acknowledge 签收

持久化

// 在队列为目的地的时候持久化消息
messageProducer.setDeliveryMode(DeliveryMode.PERSISTENT);

// 队列为目的地的非持久化消息
messageProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT)

持久化的消息,服务器宕机后消息依旧存在,只是没有入队,当服务器再次启动时,消息就会被消费

但是非持久化的消息,服务器宕机后消息永远丢失,而当你没有注明是否是持久化还是非持久化时,默认是持久化的消息。

对于目的地为主题(topic)来说,默认就是非持久化的。

让主题的订阅支持化的意义在于,对于订阅了公众号的人来说,当用户手机关机,在开机后就可以接受到关注公众号之前发送的消息。

消费者

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

    public static void main(String[] args) throws JMSException, IOException {
        System.out.println("我是1号消费者王五");
        //1.创建连接工厂,按照给定的URL,采用默认的用户名密码
        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
        //2.通过连接工厂,获得connection并启动访问
        Connection connection = activeMQConnectionFactory.createConnection();

        connection.setClientID("王五");

        //3.创建会话session
        //两个参数transacted=事务,acknowledgeMode=确认模式(签收)
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //4.创建目的地(具体是队列queue还是主题topic)
        Topic topic = session.createTopic(TOPIC_NAME);

        TopicSubscriber topicSubscriber = session.createDurableSubscriber(topic, "我是王五");

        //启动连接
        connection.start();
        Message message = topicSubscriber.receive();//一直等
        while (message != null) {
            TextMessage textMessage = (TextMessage) message;
            System.out.println("收到的持久化 topic:"+textMessage.getText());
            message = topicSubscriber.receive(3000L);//等3秒后message为空,控制台关闭。
        }
    }
}

生产者

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

    public static void main(String[] args) throws Exception{
        //1.创建连接工厂,按照给定的URL,采用默认的用户名密码
        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
        //2.通过连接工厂,获得connection并启动访问
        Connection connection = activeMQConnectionFactory.createConnection();
        connection.start();
        //3.创建会话session
        //两个参数transacted=事务,acknowledgeMode=确认模式(签收)
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //4.创建目的地(具体是队列queue还是主题topic)
        Topic topic = session.createTopic(TOPIC_NAME);
        //5.创建消息的生产者
        MessageProducer messageProducer = session.createProducer(topic);

        //设置持久化topic再启动
        messageProducer.setDeliveryMode(DeliveryMode.PERSISTENT);
        connection.start();

        //6.通过使用消息生产者,生产三条消息,发送到MQ的队列里面
        for (int i = 1; i < 4; i++) {
            //7.通过session创建消息
            TextMessage textMessage = session.createTextMessage("TOPIC_NAME---" + i);
            //8.使用指定好目的地的消息生产者发送消息
            messageProducer.send(textMessage);
        }
        //9.关闭资源
        messageProducer.close();
        session.close();
        connection.close();
        System.out.println("****TOPIC_NAME消息发布到MQ完成");
    }
}

这样就可以完成微信公众号样的功能了

posted @ 2020-08-11 13:28  柒丶月  阅读(180)  评论(0编辑  收藏  举报