Springboot项目使用RabbitMQ 实现延迟队列,延迟消息

(一)RabbitMq开启延迟队列

rabbitmq 延迟队列的实现,需要插件的支持

(二)项目设置

(1)依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

(2)yml配置

spring:
  rabbitmq:
    host: xxx
    port: xxx
    username: xxx
    password: xxx

(三)延迟消息实现核心配置

延迟对列的实现,实质主要是要定义且配置一个延迟交换机

@Bean
public Exchange delayExchange() {
          
   
    Map<String, Object> args = new HashMap<>(2);
    //  x-delayed-type    声明 延迟交换机的类型为路由直连
    args.put("x-delayed-type", "direct");
    // 设置名字 交换机类型(延迟消息) 持久化 不自动删除 
    return new CustomExchange("test-delayed-exchange", "x-delayed-message", true, false, args);
}

核心:

自定义参数定义交换机类型:

Map<String, Object> args = new HashMap<>(2);
args.put("x-delayed-type", "direct");

申明交换机中的消息为延迟消息:

上边CustomExchange 构造器中的第二个参数x-delayed-message


我们接下来进行一个完整的配置定义,我们定义交换机,定义队列,队列交换机路由件绑定

package com.leilei.delayed;

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * @author lei
 * @version 1.0
 * @date 2021/9/19 18:25
 * @desc rabbitMq延迟消息配置示例 (rabbitmq需安装 延迟消息插件  http://www.rabbitmq.com/community-plugins.html)
 */
@Configuration
public class RabbitMqDelayedConfig {
          
   


    @Bean
    public Exchange delayExchange() {
          
   
        Map<String, Object> args = new HashMap<>(2);
        //  x-delayed-type    声明 延迟队列Exchange的类型
        args.put("x-delayed-type", "direct");
        // 设置名字 交换机类型 持久化 不自动删除 
        return new CustomExchange("test-delayed-exchange", "x-delayed-message", true, false, args);
    }

    @Bean
    public Queue delayQueue() {
          
   
        return QueueBuilder.durable("test-delayed-queue").build();
    }

    /**
     * 将延迟队列通过routingKey绑定到延迟交换器
     *
     * @return
     */
    @Bean
    public Binding delayQueueBindExchange(Exchange delayExchange, Queue delayQueue) {
          
   
        return BindingBuilder.bind(delayQueue).to(delayExchange).with("leilei").noargs();
    }

}

(四)发送延迟消息

(1)延迟消息生产者

延迟消息的发送,与普通队列发送消息大部分一致,但我们需要对message做额外的延时配置

EX:

@Service
public class DelayedProvider {
          
   
    private final AmqpTemplate rabbitTemplate;

    @Autowired
    public DelayedProvider(AmqpTemplate rabbitTemplate) {
          
   
        this.rabbitTemplate = rabbitTemplate;
    }

    public void send(int delayedTime, String messageBody) {
          
   
        // 指定之前定义的延迟交换机名 与路由键名
        rabbitTemplate.convertAndSend("test-delayed-exchange", "leilei", messageBody, message -> {
          
   
            // 延迟时间单位是毫秒
            message.getMessageProperties().setDelay(delayedTime);
            System.out.println("消息发送时间:" + LocalDateTime.now()
                    .format(DateTimeFormatter.ofPattern("yyy-MM-dd HH:mm:ss")) +
                    "消息内容:" + messageBody);
            return message;
        });
    }
}

(2)延迟消息消费者

消费者端与普通的MQ消费者,一致,只需要监听对应的队列即可

@Service
public class DelayedConsumer {
          
   
    @RabbitListener(queues = "test-delayed-queue")
    public void testListenerDelayedMessage(Message message) {
          
   
        byte[] body = message.getBody();
        System.out.println(LocalDateTime.now() + new String(body));
    }
}

(五)测试

延迟15S

延迟5s

经验分享 程序员 微信小程序 职场和发展