RabbitMQ-延时队列

发布于:2025-06-18 ⋅ 阅读:(20) ⋅ 点赞:(0)

实现延时队列逻辑

RabbitMQ是没有直接实现延时队列的,可以使用死信队列或者是插件的形式实现延时队列。
本次质演示使用死信队列实现延时队列。
思想:生产者正常往RabbitMQ的正常队列中发送消息。不过这里给队列设置了TTL(消息在此队列的存活时间)。超过TTL后,消息则会进入死信队列。然后由监听死信队列的消费者消费此条消息。以此实现消息的延时。

RabbitMQConfig

队列以及交换机的配置文件

    //正常队列,消息只存在10秒,如果没有人消费,则进入死信队列,做延时消费
    @Bean("normalQueue")
    public Queue normalQueue() {
        return QueueBuilder.durable(Constants.NORMAL_QUEUE).ttl(10000).deadLetterExchange(Constants.DL_EXCHANGE).deadLetterRoutingKey("dl").build();
    }

    //正常消息的交换机
    @Bean("normalExchange")
    public DirectExchange normalExchange() {
        return ExchangeBuilder.directExchange(Constants.NORMAL_EXCHANGE).build();
    }

    //绑定关系
    @Bean("normalBinding")
    public Binding normalBinding(@Qualifier("normalQueue") Queue queue, @Qualifier("normalExchange") DirectExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with("normal");
    }

    //死信队列
    @Bean("dlQueue")
    public Queue dlQueue() {
        return QueueBuilder.durable(Constants.DL_QUEUE).build();
    }

    //死信交换机
    @Bean("dlExchange")
    public DirectExchange dlExchange() {
        return ExchangeBuilder.directExchange(Constants.DL_EXCHANGE).build();
    }

    //死信绑定关系
    @Bean("dlBinding")
    public Binding dlBinding(@Qualifier("dlQueue") Queue queue, @Qualifier("dlExchange") DirectExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with("dl");
    }
生产者
    public String sendMessage() {
        for (int i = 0; i < 10; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
	        rabbitTemplate.convertAndSend(Constants.NORMAL_EXCHANGE,"normal","hello direct " + i);
	        System.out.printf("%tc 消息发送成功 \n",new Date());
        }
        return "test fanout success...";
    }
消费者消费消息

这里只消费死信队列即可,正常的队列不消费,直接等待消息过期,进入死信队列

    @RabbitListener(queues = "dl")
    public void messageHandler(Message message) throws UnsupportedEncodingException {
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        System.out.printf("[delay.queue] %tc 接收到消息: %s, deliveryTag: %d \n",new Date(),new String(message.getBody(),"UTF-8"),deliveryTag);

        //业务处理
    }

网站公告

今日签到

点亮在社区的每一天
去签到