RabbitMQ延时队列

应用场景:饿了么下订单,若没有支付,会显示个支付倒计时,若倒计时结束,还没支付,则该消息会被送入延时队列处理
两种实现方式:1.基于参数TTL(可以在消息设置或者在队列设置),并绑定到对应的死信交换机 2.使用插件,获得一个有延迟功能的Direct交换机
两种实现方式的区别:

基于TTL的实现

在消息中设置延时

在这里插入图片描述

 //死信消息 设置TTL时间
AMQP.BasicProperties properties = new AMQP.BasicProperties().builder().expiration("10000").build();
channel.channel.basicPublish(NORMAL_EXCHANGE,"zhangsan",propertis,message.getBytes());

在队列中设置延时

放入QA中消息经过10s后会被通过绑定的死信交换机Y,送入死信队列(延迟队列)中。至于没有过期的消息如何处理,尚未可知。
在这里插入图片描述

//声明队列 B ttl 为 40s 并绑定到对应的死信交换机
@Bean("queueB")
public Queue queueB(){
   Map<String, Object> args = new HashMap<>(3);
   //声明当前队列绑定的死信交换机
   args.put("x-dead-letter-exchange", Y_DEAD_LETTER_EXCHANGE);
   //声明当前队列的死信路由 key
   args.put("x-dead-letter-routing-key", "YD");
   //声明队列的 TTL
   args.put("x-message-ttl", 40000);
   return QueueBuilder.durable(QUEUE_B).withArguments(args).build();
}

这种情况,如果要设置1h,2h,3h延时的队列就需要分别创建对应的队列,很麻烦

基于插件的实现

通过安装延时插件,可以获得一个有延时功能的Direct交换机,生产者P发布的消息(设置了延时)会被放入该交换机,等待过期之后,送入绑定的延时队列中,由C消费。至于没有过期的消息如何处理,尚未可知。

在这里插入图片描述

@Configuration
public class DelayedQueueConfig {
    public static final String DELAYED_QUEUE_NAME = "delayed.queue";
    public static final String DELAYED_EXCHANGE_NAME = "delayed.exchange";
    public static final String DELAYED_ROUTING_KEY = "delayed.routingkey";
    @Bean
    public Queue delayedQueue() {
      return new Queue(DELAYED_QUEUE_NAME);
    }
    //自定义交换机 我们在这里定义的是一个延迟交换机
    @Bean
    public CustomExchange delayedExchange() { 
      Map<String, Object> args = new HashMap<>();
      //自定义交换机的类型
      args.put("x-delayed-type", "direct");
      return new CustomExchange(DELAYED_EXCHANGE_NAME, "x-delayed-message", true, false,args);
     }
    @Bean
    public Binding bindingDelayedQueue(@Qualifier("delayedQueue") Queue queue, @Qualifier("delayedExchange") CustomExchange delayedExchange) {
     return BindingBuilder.bind(queue).to(delayedExchange).with(DELAYED_ROUTING_KEY).noargs();
     } 
}

问题

基于设置TTL的方式,消息是放在队列中的,如果前置消息没有被消费的话,后面的消息就不会被消费,也就是说,如果第一个消息设置延时20s,第二个消息设置延时2s,则因为第一个消息迟迟没有被处理,等到它过期,第二个消息早就过期了,故实际情况不应采用这种方式,所以应该采取基于插件的方式

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值