[MQ] 补充延迟队列两种方式/生产者确认机制

✨✨个人主页:沫洺的主页

📚📚系列专栏: 📖 JavaWeb专栏📖 JavaSE专栏 📖 Java基础专栏📖vue3专栏 

                           📖MyBatis专栏📖Spring专栏📖SpringMVC专栏📖SpringBoot专栏

                           📖Docker专栏📖Reids专栏📖MQ专栏📖SpringCloud专栏     

💖💖如果文章对你有所帮助请留下三连✨✨

🥞补充延迟队列不常用的两种方式

这两种方式都是基于死信队列的基础进行的

🍕创建具有超时功能的消息队列且绑定死信交换机

    //定义业务队列    
    @Bean
    public Queue directQueue() {
        return QueueBuilder.durable(QNAME)
                .deadLetterExchange(DENAME) //通过这两个配置,使我们的业务队列与死信交换机有关系了
                .deadLetterRoutingKey(DKEY)
                .ttl(60*1000) //设置消息多久过期,消息超过这个时间就直接给死信交换机,让它处理
                .maxLength(1000) //设置队列最大容量,超过这个容量就直接给死信交换机,让它处理
                .build();
    }

简单来讲,就是通过ttl设置消息过期时间,消息队列没有消费者去应答,超过过期时间后,消息会进入死信队列,这个时候将死信队列就相当于延迟队列,监听死信队列,即可处理超时的消息队列

缺点

这种方式,ttl延时队列中所有的消息超时时间都是一样的,如果不同消息想设置不一样的超时时间,就需要建立多个不同超时时间的消息队列,比较麻烦,且不利于维护。

🍟创建消息队列且绑定死信交换机设置通用延时消息

    rabbitTemplate.convertAndSend("交换机名称", "RoteingKey","对象",message
        => {
            //设置消息延迟时间5秒,5秒之后交给消费者,针对的是队列
            message.getMessageProperties().setExpiration(String.valueOf(5000))             
            return message;
           }
    );

相较于上面的ttl对所有消息设置过期时间而言,该方法可以针对某一条具体的消息设置延迟时间,当队列的ttl和setExpiration同时设置时,以最小的值为准

缺点

该种方式可以创建一个承载不同超时时间消息的消息队列,但是这种方式有一个问题,如果消息队列中排在前面的消息没有到超时时间,即使后面的消息到了超时时间,先到超时时间的消息也不会进入死信队列,而是先检查排在最前面的消息队列是否到了超时时间,如果到了超时时间才会继续检查后面的消息,原理就是队列的先进先出.

补充:

这种对消息设置延迟时间的方式和通过延迟插件设置消息延迟时间的区别

//设置消息延迟时间5秒,5秒之后投递给队列 针对的是交换机
message.getMessageProperties().setDelay(5*1000);
//设置消息延迟时间5秒,5秒之后交给消费者,针对的是队列
message.getMessageProperties().setExpiration(String.valueOf(5000));
  • 延迟插件设置消息延迟是在交换机中进行的,延迟结束后传递给消息队列
  • 而这种消息延迟是在消息队列中进行的,延迟结束后传递给死信队列

🧇生产者确认机制 

生产者最关心的两个点

  1.  生产者生产的消息有没有投递到交换机里
  2. 投递后交换机有没有将消息路由给队列 

添加配置

#开启强制消息投递(mandatory为设置为true),但消息未被路由至任何一个queue,
#则回退一条消息到RabbitTemplate.ReturnCallback中的returnedMessage方法:
spring.rabbitmq.template.mandatory = true
#开启交换机发布确认模式,交换机收到或者未收到消息, 都会调用回调实现类的回调确认方法
spring.rabbitmq.publisher-confirm-type=correlated
#开启回退消息 , 当交换机无法将消息路由出去, 便会将消息回退给生产者
spring.rabbitmq.publisher-returns=true

实现两个接口

  • RabbitTemplate.ConfirmCallback
    •  通过实现 ConfirmCallback 接口,消息发送到 Broker 后触发回调,确认消息是否到达 Broker 服务器,也就是只确认是否正确到达 Exchange 中。
  • RabbitTemplate.ReturnsCallback
    •  通过实现 ReturnCallback 接口,发送消息失败返回,比如路由不到队列时触发回调

  

模拟当没有交换机时

    

    

  

模拟当交互机存在,但没有队列时 

  

  

补充:

在交换机确认回调函数中参数一: correlationData(相关数据)

在一些实际业务中会用到该参数,例如订单状态id等,通过状态id确认订单状态

  

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沫洺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值