JMS(ActiveMQ)消息可靠性(持久性,事务,签收)

本文深入探讨JMS消息队列的核心概念,包括持久性和非持久性消息的处理,事务在生产者和消费者中的应用,以及不同签收模式的实现细节。通过示例代码,展示如何配置消息的持久化、开启事务处理,并手动进行消息签收,确保消息传递的可靠性和事务的一致性。
摘要由CSDN通过智能技术生成

持久性

非持久:当服务器宕机,消息不存在

messageProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);

持久化:当服务器宕机,消息依然存在

messageProducer.setDeliveryMode(DeliveryMode.PERSISTENT);

事务

生产者事务

当我们在创建一个session的时候,我们可以指定是否开启事务,代码如下:
false:表示不开启事务,只要执行send方法,表示消息就进入到队列中
true:表示开启事务,

Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

当把事务 设为 true的时候 ,当我们发送消息的时候,需要手动提交,代码 session.commit()

事务的作用:
当我们批处理一次发送多个个消息,如果中间一条消息出现了异常,我们可以利用事务控制,该批消息要么全部发送成功,要么可以回滚,

示例代码:

public class ActivemqProducer {
    static String BROCKER_URL = "tcp://192.168.72.129:61616";
    static String QUEUE_NAME = "queue_name01";

    public static void main(String[] args) throws JMSException {
        // 1. 创建连接工厂
        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(BROCKER_URL);
        // 2. 获取连接 并启动
        Connection connection = activeMQConnectionFactory.createConnection();
        connection.start();
        // 3. 创建session 并开启事务,参数一:事务,参数二:签收
        Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
        //4. 创建目的地,队列
        Queue queue = session.createQueue(QUEUE_NAME);
        // 5.创建消息生产者
        MessageProducer messageProducer = session.createProducer(queue);

        try {
            // 6.通过 messageProducer 发送3条消息
            for (int i = 1; i <= 3; i++) {
                TextMessage textMessage = session.createTextMessage("消息 ->" + i);
                messageProducer.send(textMessage);
            }
            // 提交事务
            session.commit();
        } catch (JMSException e) {
            // 回滚
            session.rollback();
            e.printStackTrace();
        }
        
        System.out.println("发送消息完成......");
        // 7.关闭资源
        messageProducer.close();
        session.close();
        connection.close();
    }
}

消费者事务

当消费者开启事务,如果我们消费了消息,不提交事务,那么消息将一直不出队列,该消息可以一直被消费,可以被重复消费

当我们在消费消息的时候,如果其中一个消息出现异常,我们可以重新消费

签收(Acknowledge)

在创建session的时候我们可以指定 签收模式,签收模式有以下几种:

  1. 自动签收 Session.AUTO_ACKNOWLEDGE
  2. 手动签收 Session.CLIENT_ACKNOWLEDGE
  3. 允许重复消息 Session.DUPS_OK_ACKNOWLEDGE
  4. 以事务方式 Session.SESSION_TRANSACTED

签收注意侧重 消费者

自动签收

该模式下当我们消费者消费了消息,那么该 消息就自动签收了,消息出队列。

CLIENT_ACKNOWLEDGE(手动签收)

该模式下,消费者以非事务的方式消费消息。

  1. 如果不手动签收,那么该消息就不会出队列,
  2. 需要对消费的每一条消息确认签收: message.acknowledge();
  3. 这样消息确认消费了,我们手动签收,消息出队列,可以保证消息的可靠性

如果开启了事务的同时也开启了CLIENT_ACKNOWLEDGE,那么以事务的commit为准,什么时候commit,消息什么时候出队列,与确认签收无关了

public class ActivemqConsumer {
    static String BROKER_URL = "tcp://192.168.72.129:61616";
    static String QUEUE_NAME = "queue_name04";

    public static void main(String[] args) throws JMSException {
        // 1.创建连接工厂
        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(BROKER_URL);
        // 2.创建连接并启动
        Connection connection = activeMQConnectionFactory.createConnection();
        connection.start();
        // 3.创建session
        Session session = connection.createSession(true, Session.CLIENT_ACKNOWLEDGE);
        // 4.创建目的地
        Queue queue = session.createQueue(QUEUE_NAME);
        // 5.创建消费者
        MessageConsumer consumer = session.createConsumer(queue);


        // 6.从目的地取消息
        while (true) {
            // 如果没有消息,g该方法会阻塞
            TextMessage message = (TextMessage) consumer.receive();
            if (message != null) {
                System.out.println("消费者收到消息:" + message.getText());
                // 手动签收
                message.acknowledge();
            } else
                break;
        }
        // 7.关闭资源
        consumer.close();
        session.close();
        connection.close();
    }
}

签收和事务的关系

在事务的会话中,当一个事务被成功提交则消息被自动签收。
如果事务回滚,则消息会被再次传送。(以事务为大)

非事务的回话中,消息何时被确认签收取决于创建session时设置的签收模式

JMS点对点,发布订阅总结

点对点:
在这里插入图片描述
发布订阅:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值