rabbitmq实战系列1--springboot整合rabbitmq实现延迟队列(1)

什么是延迟队列?

延时队列顾名思义,即放置在该队列里面的消息是不需要立即消费的,而是等待一段时间之后取出消费。
那么,为什么需要延迟消费呢?我们来看以下的场景

1需要实现消息推送功能.
2网上商城下订单后30分钟后没有完成支付,取消订单(如:淘宝、去哪儿网)
3系统创建了预约之后,需要在预约时间到达前一小时提醒被预约的双方参会
4系统中的业务失败之后,需要重试,

- 原生TTL,DLX版本

TTL
RabbitMQ可以针对队列设置x-expires(则队列中所有的消息都有相同的过期时间)或者针对Message设置x-message-ttl(对消息进行单独设置,每条消息TTL可以不同),来控制消息的生存时间,如果超时(两者同时设置以最先到期的时间为准),则消息变为dead letter(死信)

Dead Letter Exchanges(DLX)
RabbitMQ的Queue可以配置x-dead-letter-exchange和x-dead-letter-routing-key(可选)两个参数,如果队列内出现了dead letter,则按照这两个参数重新路由转发到指定的队列。
x-dead-letter-exchange:出现dead letter之后将dead letter重新发送到指定exchange
x-dead-letter-routing-key:出现dead letter之后将dead letter重新按照指定的routing-key发送

注意:x-dead-letter-exchange和x-dead-letter-routing-key是绑定在队列上的,不是交换机上
步骤:
在这里插入图片描述

  1. 配置config
@Configuration
public class ttl {
    @Bean
    public Queue delayQueue(){
        Map<String,Object> map = new HashMap<>(16);
        map.put("x-dead-letter-exchange","receive_exchange");
        map.put("x-dead-letter-routing-key","receive_key");
        //绑定消息到期后发送的交换机以及routing-key
        return new Queue("delay_queue",true,false,false,map);
    }
    @Bean
    public DirectExchange delayExchange(){
        return new DirectExchange("delay_exchange");
    }
    @Bean
    public Binding delayBind(){
        return BindingBuilder.bind(delayQueue()).to(delayExchange()).with("delay_key");
    }
    @Bean
    public DirectExchange receiveExchange(){
        return new DirectExchange("receive_exchange");
    }

    /**
     * 死信接收队列
     * @return
     */
    @Bean
    public Queue receiveQueue(){
        return new Queue("receive_queue");
    }

    /**
     * 死信交换机绑定消费队列
     * @return
     */
    @Bean
    public Binding receiveBinding(){
        return BindingBuilder.bind(receiveQueue()).to(receiveExchange()).with("receive_key");
    }

}

  1. 生产者
@Component
public class ttltest {
    @Autowired
    RabbitTemplate template;
    public void send(List<Integer> list){
        System.out.println("发送时间:"+ LocalDateTime.now());
        template.convertAndSend("delay_exchange","delay_key",list,message ->{
            message.getMessageProperties().setExpiration("6000");
            return message;
        } );
        System.out.println("6000ms后将会执行任务");
    }
}
  1. 消费者
@Component
@RabbitListener(queues = "receive_queue")
public class ttlConsumer1 {
    @RabbitHandler
    public void hand(List<Integer>list){
          System.out.println("接收到了消息,现在时间是:"+ LocalDateTime.now());
          System.out.println(list.toString());
      }
}

5.测试类


@RunWith(SpringRunner.class)
@SpringBootTest
public class test1 {
    @Autowired
    ttltest ttltest;
    @Test
    public void test1(){
        List<Integer>list = new LinkedList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        ttltest.send(list);
    }
}

注意:
这种方式实现延迟队列,根据队列的先进先出原则,会造成队列阻塞,导致先到时的应为阻塞而无法实现.解决方法在下一篇文章中有涉及

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值