什么都不必说--rabbitMQ 延迟队列

189 阅读1分钟
场景:业务需求,订单在指定时间后进行逻辑操作

config类中设置

 /**
     * 方法rabbitAdmin的功能描述:动态声明queue、exchange、routing
     *
     * @param connectionFactory
     * @return
     * @author : yuhao.wang
     */
    @Bean
    public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
        RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
        //声明死信队列(Fanout类型的exchange)
        Queue deadQueue = new Queue(Constants.QUEUE_NAME_DEAD_QUEUE);
        // 死信队列交换机
        FanoutExchange deadExchange = new FanoutExchange(Constants.MQ_EXCHANGE_DEAD_QUEUE);
        rabbitAdmin.declareQueue(deadQueue);
        rabbitAdmin.declareExchange(deadExchange);
        rabbitAdmin.declareBinding(BindingBuilder.bind(deadQueue).to(deadExchange));

        // 发放奖励队列交换机
        DirectExchange exchange = new DirectExchange(Constants.MQ_EXCHANGE_SEND_AWARD);

        //声明的消息队列(Direct类型的exchange)
        Queue couponQueue = queue(Constants.QUEUE_NAME_SEND_COUPON);
        rabbitAdmin.declareQueue(couponQueue);
        rabbitAdmin.declareExchange(exchange);
        rabbitAdmin.declareBinding(BindingBuilder.bind(couponQueue).to(exchange).with(Constants.MQ_ROUTING_KEY_SEND_COUPON));

        return rabbitAdmin;
    }

    public Queue queue(String name) {
        Map<String, Object> args = new HashMap<>();
        // 设置死信队列
        args.put("x-dead-letter-exchange", Constants.MQ_EXCHANGE_DEAD_QUEUE);
        args.put("x-dead-letter-routing-key", Constants.MQ_ROUTING_KEY_DEAD_QUEUE);
        // 设置队列的过期时间, 单位是毫秒
        args.put("x-message-ttl", 5000);

        // 是否持久化
        boolean durable = true;
        // 仅创建者可以使用的私有队列,断开后自动删除
        boolean exclusive = false;
        // 当所有消费客户端连接断开后,是否自动删除队列
        boolean autoDelete = false;
        return new Queue(name, durable, exclusive, autoDelete, args);
    }

添加延迟消费者

@Component
public class DelayReceiver {

    @RabbitListener(queues = Constants.QUEUE_NAME_DEAD_QUEUE)
    public void process(String sendMessage) throws Exception {
        System.out.println("收到的消息"+sendMessage);
        log.info("时间({}),消息体:{}",new Date()+"", sendMessage);
    }

}

发送消息测试

  rabbitTemplate.convertAndSend(Constants.QUEUE_NAME_SEND_COUPON, new Date()+"");

如上,只能根据队列的过期时间,来做到延迟. 那么,如何动态的修改延迟时间?

MessageProperties properties = new MessageProperties();
properties.setDeliveryMode(MessageDeliveryMode.PERSISTENT);
 //设置消息过期时间
properties.setExpiration(time);
// 当队列过期时间和消息过期时间同时存在时,按照最短的时间进行过期

Message message  = new SimpleMessageConverter().toMessage(data,properties);
rabbitTemplate.send(queueName,message);