SpringBoot RabbitMQ 实现延迟队列

SpringBoot RabbitMQ 实现延迟队列

一.依赖
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
二.Config 类
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

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

@Configuration
public class MqConfig {
    
    

    //延时交换机
    public static final String DELAY_EXCHANGE_NAME = "delay.exchange";
    //死信交换机
    public static final String DEAD_LETTER_EXCHANGE = "dead.exchange";
    //延时队列
    public static final String DELAY_QUEUE_NAME = "delay.queue";
    //死信队列
    public static final String DEAD_LETTER_QUEUE_NAME = "dead.queue";
    //延时队列路由key
    public static final String DELAY_QUEUE_ROUTING_KEY = "delay.queue.routingKey";
    //死信对列路由key
    public static final String DEAD_LETTER_QUEUE_ROUTING_KEY = "dead.queue.routingKey";


    // 声明延时Exchange
    @Bean("delayExchange")
    public DirectExchange delayExchange(){
    
    
        return new DirectExchange(DELAY_EXCHANGE_NAME);
    }

    // 声明死信Exchange
    @Bean("deadExchange")
    public DirectExchange deadLetterExchange(){
    
    
        return new DirectExchange(DEAD_LETTER_EXCHANGE);
    }

    // 声明延时队列 不设置TTL
    // 并绑定到对应的死信交换机
    @Bean("delayQueue")
    public Queue delayQueue(){
    
    
        Map<String, Object> args = new HashMap<>(3);
        // x-dead-letter-exchange    这里声明当前队列绑定的死信交换机
        args.put("x-dead-letter-exchange", DEAD_LETTER_EXCHANGE);
        // x-dead-letter-routing-key  这里声明当前队列的死信路由key
        args.put("x-dead-letter-routing-key", DEAD_LETTER_QUEUE_ROUTING_KEY);
        return QueueBuilder.durable(DELAY_QUEUE_NAME).withArguments(args).build();
    }

    // 声明死信队列 用于接收延时任意时长处理的消息
    @Bean("deadLetterQueue")
    public Queue deadLetterQueue(){
    
    
        return new Queue(DEAD_LETTER_QUEUE_NAME);
    }

    // 声明延时列绑定关系
    @Bean
    public Binding delayBinding(@Qualifier("delayQueue") Queue queue,
                                 @Qualifier("delayExchange") DirectExchange exchange){
    
    
        return BindingBuilder.bind(queue).to(exchange).with(DELAY_QUEUE_ROUTING_KEY);
    }

    // 声明死信队列绑定关系
    @Bean
    public Binding deadLetterBinding(@Qualifier("deadLetterQueue") Queue queue,
                                      @Qualifier("deadExchange") DirectExchange exchange){
    
    
        return BindingBuilder.bind(queue).to(exchange).with(DEAD_LETTER_QUEUE_ROUTING_KEY);
    }
}
三.延时消息发送类
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import static com.meng.mq.config.MqConfig.*;

@Component
public class DelayMessageSender {
    
    

    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void sendMsg(String msg,Integer delayTime){
    
    
        rabbitTemplate.convertAndSend(DELAY_EXCHANGE_NAME, DELAY_QUEUE_ROUTING_KEY, msg,message -> {
    
    
            //设置消息持久化
            message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
            //设置消息延时时间
            message.getMessageProperties().setDelay(delayTime * 1000);
            //设置消息过期时间
            message.getMessageProperties().setExpiration(delayTime*1000+"");
            return message;
        });
    }
}
四.生产者(发送消息)
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;

@Slf4j
@RestController
public class RabbitMQMsgController {
    
    

    @Autowired
    private DelayMessageSender sender;

    @RequestMapping("sendmsg")
    public void sendMsg(String msg, Integer delayTime){
    
    
        log.info("当前时间:{},收到请求,msg:{}", new Date(), msg);
        sender.sendMsg(msg,delayTime);
    }
}
五.消费者(接受消息)
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import java.io.IOException;

@Component
public class TopicManReceiver {
    
    

    @RabbitListener(queues = "dead.queue")
    public void receive(Message message) throws IOException {
    
    
        String msg = new String(message.getBody());
        System.out.println(msg);
    }
}
六.验证

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/hsadfdsahfdsgfds/article/details/114676207