ActiveMQ签收_10

事务主要是偏向生产者,签收主要是偏向消费者。

再来看签收参数,之前我们设置的是Session.AUTO_ACKNOWLEDGE,也就是自动签收,可以理解为快递员自动给你签收了并放到了快递柜中。当然还有手动签收,也就是见到快递员,开箱验货,再签收的意思。

自动签收(默认):Session.AUTO_ACKNOWLEDGE。

手动签收:Session.CLIENT_ACKNOWLEDGE,客户端调用acknowledge()方法手动签收,如果忘记了写acknowledge()方法,下次再启动的时候,就会重复消费,因为消费者签收过了却没有告知MQ。

带副本允许重复签收(用的很少):Session.DUPS_OK_ACKNOWLEDGE。

生产者:将事务设置成了false,另外去掉了session.commit();手动提交,代码前几篇的可以复用。

消费者:将事务设置成了false,另外去掉了session.commit();手动提交,并将Session.AUTO_ACKNOWLEDGE改为Session.CLIENT_ACKNOWLEDGE,并在输出textMessage的时候,调用了textMessage.acknowledge()方法手动签收。

非事务--手动签收

主要来看消费者的代码

public class JmsConsumer_TX {

    public static final String ACTIVEMQ_URL = "tcp://10.5.96.48:61616";
    public static final String  QUEUE_NAME = "queue-atguigu";

    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.创建会话
        /*****改成非事务-手动签收 start ****/
        Session session = connection.createSession(false,Session.CLIENT_ACKNOWLEDGE);
        /*****改成非事务-手动签收 end ****/
        //4.创建目的地
        Queue queue = session.createQueue(QUEUE_NAME);
        //5.创建消费者
        MessageConsumer messageConsumer = session.createConsumer(queue);
        while (true)
        {
            TextMessage textMessage = (TextMessage) messageConsumer.receive(4000);
            if(null != textMessage){
                System.out.println("********消费者接收消息:"+ textMessage.getText());
            }else{
                break;
            }
        }
        messageConsumer.close();
        session.close();
        connection.close();
    }
}

如果没有增加 textMessage.acknowledge()方法手动签收 则会重复的消费

需要在while循环里面增加如下代码

while (true)
        {
            TextMessage textMessage = (TextMessage) messageConsumer.receive(4000);
            if(null != textMessage){
                System.out.println("********消费者接收消息:"+ textMessage.getText());
                /****非事务手动签收 调用 acknowledge()方法 start ****/
                textMessage.acknowledge();
                /****非事务手动签收 调用 acknowledge()方法 end ****/
            }else{
                break;
            }
        }

 事务的手动签收

将生产者和消费者代码中的事务再次开启,记得加session.commit();然后将消费者的签收模式改为手动签收,故意不写acknowledge()方法的调用,启动生产者,启动消费者,这时候,消费者可以拿到消息,再次启动消费者,却不会出现重复消费的情况,这是为什么呢?我们可以理解为执行了提交操作,也就告知了MQ,消费者已经完成了签收,这里的CLIENT.ACKNOWLEDGE也就相当于AUTO_ACKNOWLEDGE了。

前面的代码是有session.commit();方法,没有textMessage.acknowledge();方法,再来做个试验,只有textMessage.acknowledge();方法,却没有session.commit();方法,会是什么结果呢?

结果发现,消费者可以重复消费。

可以理解为:事务的作用 > 签收的作用。

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

在非事务性会话中,消息何时被确认取决于创建会话的签收模式

JMS的可靠性 从四可以说明

      1.Persistent 持久性

      2.transaction 事务

      3 Acknowledge 签收 

     4 集群  (后面说) 以上几点比较重要

总结      

点对点模型是基于队列的,生产者发送消息到队列,消费者从队列取消息,队里的存在使得消息的异步传输称为可能。类似于发短信。

如果session关闭时,有部分消息被收到但是还没有被签收(acknowledge),当消费者下次再连接到相同队列的时候,消息会被再次接收。

队列可以长久的保存消息直到消费者接收到消息,消费者不需要因为担心消息会丢失而时刻保持会话持久连接,充分体现了异步传输模式的优势。

JMS的pub/sub模式定义了如何向有关内容结点发布和订阅消息,这些结点叫做topic

主题可以被认为是消息的传输中介,发布者发布消息主题,订阅者从主题鼎业消息。

主题使得消息订阅者和消息发布者互相独立,不需要接触即可保证消息的传送,也就是订阅者不需要关心发布者,发布者也不需要关心订阅者。

非持久订阅只有当客户端处于激活状态,也就是和MQ保持连接状态才能收到发送到某个主题的消息。

如果消费者处于离线状态,生产者发送的主题消息将会丢失,消费者永远也收不到。

先订阅注册才能接受发布,只给订阅者发布消息。也就是前面说的,先启动消费者,后启动生产者。

持久化订阅,客户端需要先向MQ注册一个ID识别号。当这个客户端处于离线时,生产者会为这个ID保存所有发送到主题的消息,当客户端再次连接到MQ时,会根据消费者的ID得到所有当自己处于离线时错过的消息。

非持久化订阅状态下,不能恢复或重新发送一个未签收的消息。只有持久化的时候,才会恢复或重新发送未签收消息。

通常情况下,都不希望丢消息吧,所以实际应用中,持久化订阅用的更多一些。
 

参考

原文链接:https://blog.csdn.net/qq_36059561/article/details/103814082

原文链接:https://blog.csdn.net/qq_36059561/article/details/103814046

原文链接:https://blog.csdn.net/qq_36059561/article/details/103814095

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值