ActiveMQ笔记(三)如何保证消息可靠性

一 持久化

1.1 API设置

java默认是持久化的
在这里插入图片描述
在这里插入图片描述

1.2 Topic持久化

默认情况下,topic发布时,如果订阅者不在线。消息就会丢失

但我们可以用持久化Topic来解决这个问题。

先启动订阅在启动生产

生产者

变化不多

package com.zyc.activemqdemo.consumer;





import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

/**
 * @ClassName JmsProduce
 * @Description TODO
 * @Author DuanYueFeng
 * @Version 1.0
 **/
public class JmsProduce_Topic_p {
    public static final String URL = "tcp://192.168.196.4:61616";
    public static final String topic_name = "topic_p";

    public static void main(String[] args) throws JMSException {
        ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(URL);
        Connection connection = factory.createConnection();

        Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
        Topic topic = session.createTopic(topic_name);
        MessageProducer producer = session.createProducer(topic);
        producer.setDeliveryMode(DeliveryMode.PERSISTENT);

        connection.start();//start放后面

        for (int i = 1; i <=3; i++) {
            TextMessage textMessage = session.createTextMessage("Topic mag..." + i);
            producer.send(textMessage);
        }
        producer.close();
        session.close();
        connection.close();
        System.out.println("完成....");
    }
}




订阅者

package com.zyc.activemqdemo.consumer;


import org.apache.activemq.ActiveMQConnectionFactory;


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

/**
 * @ClassName JmsConsumer
 * @Description TODO
 * @Author DuanYueFeng
 * @Version 1.0
 **/
public class JmsConsumer_Topic_p {
    public static final String URL = "tcp://192.168.196.4:61616";
    public static final String topic_name = "topic_p";

    public static void main(String[] args) throws JMSException, IOException, InterruptedException {
        System.out.println("我是3号消费者。。。");
        ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(URL);
        Connection connection = factory.createConnection();
        connection.setClientID("z3");//订阅者的客户端id
        Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
        Topic topic = session.createTopic(topic_name);
        TopicSubscriber durableSubscriber = session.createDurableSubscriber(topic, "remark..");//后面是订阅者的名称

        connection.start();//start也要延后

        Message message = durableSubscriber.receive();

        while (null!=message){
            TextMessage textMessage = (TextMessage)message;
            System.out.println("收到的持久化:"+textMessage.getText());
            message = durableSubscriber.receive(1000L);
        }

        System.in.read();
//        Thread.sleep(1000);
        session.close();
        connection.close();
        System.out.println("完成....");
    }
}

二 事务

事务偏生产者

2.1 生产者事务

事务的配置优先度高于应答模式(签收)

		//第一个参数是是否创建session,第二个参数表示应答模式
        Session session = connection.createSession(true,Session.AUTO_ACKNOWLEDGE);

不开启事务时
只要执行send就进入到队列中

开启事务后
需要在最后使用session.commit();,某一条异常也可以用session.rollback();

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

2.2 消费者事务

不开启事务时
消息拿到就算作被消费了

开启事务时
没有commit,消息就不会算作被消费。会有重复消费的可能

三 签收

签收偏消费者

3.1 非事务模式

自动签收(默认)

Session.AUTO_ACKNOWLEDGE

手动签收

Session.CLIENT_ACKNOWLEDGE
客户端调用acknowledge方法手动签收
在这里插入图片描述

允许重复消息

Session.DUPS_OK_ACKNOWLEDGE

消息可重复确认,意思是此模式下,可能会出现重复消息,并不是一条消息需要发送多次ACK才行。它是一种潜在的"AUTO_ACK"确认机制,为批量确认而生,而且具有“延迟”确认的特点。对于开发者而言,这种模式下的代码结构和AUTO_ACKNOWLEDGE一样,不需要像CLIENT_ACKNOWLEDGE那样调用acknowledge()方法来确认消息。

3.2 事务模式下

消费者事务开启,只有commit后才能将全部消息变为已消费,写ack没有作用,即使写了签收也不会签收出队

3.3 和事务的联系

  1. 在事务性会话中,当一个事务被成功提交则消息被自动签收。如果事务回滚,则消息会被再次传送
  2. 非事务会话中,消息何时被确认取决于创建会话时的应答模式(acknowledgement)

四 Broker

就是可以创建一个迷你的mq服务器

4.1 是什么

在这里插入图片描述

4.2 不同的conf配置文件模拟不同的实例

原来并没有`后面的那一部分制定配置文件的命令
在这里插入图片描述

4.3 嵌入式Broker

依赖

在这里插入图片描述

启动

package com.atguigu.activemq.embed;

import org.apache.activemq.broker.BrokerService;

/**
 * @ClassName EmbedBroker
 * @Description TODO
 * @Author DuanYueFeng
 * @Version 1.0
 **/
public class EmbedBroker {
    public static void main(String[] args) throws Exception {
        BrokerService brokerService = new BrokerService();
        brokerService.setUseJmx(true);
        brokerService.addConnector("tcp://localhost:61616");
        brokerService.start();
    }
}
发布了82 篇原创文章 · 获赞 1 · 访问量 1953

猜你喜欢

转载自blog.csdn.net/m0_38060977/article/details/103751868