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";
public static final String DELAY_QUEUE_ROUTING_KEY = "delay.queue.routingKey";
public static final String DEAD_LETTER_QUEUE_ROUTING_KEY = "dead.queue.routingKey";
@Bean("delayExchange")
public DirectExchange delayExchange(){
return new DirectExchange(DELAY_EXCHANGE_NAME);
}
@Bean("deadExchange")
public DirectExchange deadLetterExchange(){
return new DirectExchange(DEAD_LETTER_EXCHANGE);
}
@Bean("delayQueue")
public Queue delayQueue(){
Map<String, Object> args = new HashMap<>(3);
args.put("x-dead-letter-exchange", DEAD_LETTER_EXCHANGE);
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);
}
}
六.验证