RabbitMQ-延迟队列代码实践

延迟队列的本质用的到时死信,如下情况下消息会变为死信
1 被 拒 绝 、 n a c k 并 且 没 有 重 新 入 队 的 消 息 \color{#FF0000}{被拒绝、nack并且没有重新入队的消息} nack
2 消息过期
3 队列达到了最大长度。
成为死信的消息可以进入死信交换机,然后进入另外一个队列中。

两个交换器和队列如下
在这里插入图片描述

//--------------------------死信队列测试------------------

    public static final String NORMAL_QUEUE_NAME="queue.normal";

    public static final String NORMAL_EXCHANGE_NAME="exchange.normal";

    public static final String NORMAL_ROUTING_KEY ="normal.routing.key";

    @Bean
    public Queue normalQueue(){
        //设置死信队列
        Map<String,Object> arguments=new HashMap<>();
        arguments.put("x-dead-letter-exchange",DEAD_EXCHANGE_NAME);
        arguments.put("x-dead-letter-routing-key",DEAD_LETTER_ROUTING_KEY);
        //设置过期时间为10秒
        arguments.put("x-message-ttl",10000);
       return new Queue(NORMAL_QUEUE_NAME, true, false, false,arguments);
    }

    @Bean
    public DirectExchange normalExchange(){
        return new DirectExchange(NORMAL_EXCHANGE_NAME,true,false);
    }

    @Bean
    public Binding normalExchangeBindQueue(){
        return BindingBuilder.bind(normalQueue())
                .to(normalExchange())
                .with(NORMAL_ROUTING_KEY);
    }

    public static final String DEAD_LETTER_ROUTING_KEY ="dead.letter.test";

    public static final String DEAD_EXCHANGE_NAME="exchange.dlx";

    public static final String DEAD_QUEUE_NAME="queue.dlx";

    @Bean
    public Queue deadQueue(){
        return new Queue(DEAD_QUEUE_NAME);
    }

    @Bean
    public DirectExchange deadExchange(){
        return new DirectExchange(DEAD_EXCHANGE_NAME,true,false);
    }

    /**
     * 死信队列与交换器绑定
     * @return
     */
    @Bean
    public Binding deadExchangeBindQueue(){
        return BindingBuilder.bind(deadQueue())
                .to(deadExchange())
                .with(DEAD_LETTER_ROUTING_KEY);
    }

发送

@Autowired
    private RabbitTemplate rabbitTemplate;

    public void sendMsg(){
        //发送Map对象
        Map<String,Object> map=new HashMap<>();
        map.put("id",1);
        map.put("username","张三");
        map.put("password","123");

        //设置消息唯一id
        CorrelationData correlationData=new CorrelationData();
        correlationData.setId(1+"");
        logger.info("发送时间{}",System.currentTimeMillis());
        rabbitTemplate.convertAndSend(RabbitMQConfig.NORMAL_EXCHANGE_NAME,//exchange
                RabbitMQConfig.NORMAL_ROUTING_KEY,//rountingKey
                map,//
                correlationData);
    }

接收方:

/**
     * 死信队列
     * @param user
     * @param headers
     * @param channel
     * @throws IOException
     */
    @RabbitListener(queues = "queue.dlx")
    @RabbitHandler
    public void onUserInfoMessage(@Payload Map user,
                                  @Headers Map<String, Object> headers, Channel channel) throws IOException {
        //消费者操作
        logger.info("接收到的消息【{}】", user.toString());
        logger.info("接受到消息的时间{}",System.currentTimeMillis());

        //确认签收
        Long deliveryTag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);
        channel.basicAck(deliveryTag, false);
    }

控制台打印的两个时间正好相差10秒。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值