一、导入依赖
<!--springboot依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--springboot测试依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--RabbitMQ依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
<!--fastjson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.78</version>
</dependency>
<!--Rabbitmq测试依赖-->
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit-test</artifactId>
<version>2.3.9</version>
</dependency>
二、队列配置文件
需要一台普通交换机,一台死信交换机,两个普通队列,一个死信队列,在普通队列设置参数绑定死信交换机,并设置过期时间(多少毫秒后队列未接收到消息则发给死信交换机)
//设置死信交换机
arguments.put("x-dead-letter-exchange", Y_DEAD_LETTER_EXCHANGE);
//设置死信交换机的routing-key
arguments.put("x-dead-letter-routing-key", "dead_key");
//设置过期时间
arguments.put("x-message-ttl", 10000);
@Configuration
public class TtlQueueConfig {
//普通交换机
private static final String X_EXCHANGE ="X";
//延迟交换机
private static final String Y_DEAD_LETTER_EXCHANGE ="Y";
//普通队列
private static final String QUEUE_A ="QA";
private static final String QUEUE_B ="QB";
//优化队列 不设置过期时间
private static final String QUEUE_C ="QC";
//死信队列
private static final String QUEUE_D ="QD";
//声明交换机
@Bean("xExchange")
public DirectExchange xExchange() {
return new DirectExchange(X_EXCHANGE);
}
@Bean("yExchange")
public DirectExchange yExchange() {
return new DirectExchange(Y_DEAD_LETTER_EXCHANGE);
}
//声明普通队列A
@Bean("queueA")
public Queue queueA() {
Map<String, Object> arguments = new HashMap<>();
//设置死信交换机
arguments.put("x-dead-letter-exchange", Y_DEAD_LETTER_EXCHANGE);
//设置死信交换机的routing-key
arguments.put("x-dead-letter-routing-key", "dead_key");
//设置过期时间
arguments.put("x-message-ttl", 10000);
//设置队列长度
//arguments.put("x-max-length", 6)
return QueueBuilder.durable(QUEUE_A).withArguments(arguments).build();
}
//声明普通队列B
@Bean("queueB")
public Queue queueB() {
Map<String, Object> arguments = new HashMap<>();
//设置死信交换机
arguments.put("x-dead-letter-exchange", Y_DEAD_LETTER_EXCHANGE);
//设置死信交换机的routing-key
arguments.put("x-dead-letter-routing-key", "dead_key");
//设置过期时间
arguments.put("x-message-ttl", 40000);
return QueueBuilder.durable(QUEUE_B).withArguments(arguments).build();
}
//声明优化普通队列C
@Bean("queueC")
public Queue queueC() {
Map<String, Object> arguments = new HashMap<>();
//设置死信交换机
arguments.put("x-dead-letter-exchange", Y_DEAD_LETTER_EXCHANGE);
//设置死信交换机的routing-key
arguments.put("x-dead-letter-routing-key", "dead_key");
return QueueBuilder.durable(QUEUE_C).withArguments(arguments).build();
}
//声明死信队列D
@Bean("queueD")
public Queue queueD() {
return QueueBuilder.durable(QUEUE_D).build();
}
//绑定交换机
@Bean
public Binding queueABindingX(@Qualifier("queueA") Queue queueA,
@Qualifier("xExchange") DirectExchange xExchange) {
return BindingBuilder.bind(queueA).to(xExchange).with("XA");
}
@Bean
public Binding queueBBindingX(@Qualifier("queueB") Queue queueB,
@Qualifier("xExchange") DirectExchange xExchange) {
return BindingBuilder.bind(queueB).to(xExchange).with("XB");
}
@Bean
public Binding queueDBindingY(@Qualifier("queueD") Queue queueD,
@Qualifier("yExchange") DirectExchange yExchange) {
return BindingBuilder.bind(queueD).to(yExchange).with("dead_key");
}
@Bean
public Binding queueCBindingX(@Qualifier("queueC") Queue queueC,
@Qualifier("xExchange") DirectExchange yExchange) {
return BindingBuilder.bind(queueC).to(yExchange).with("XC");
}
}
三、生产者
//只发送消息内容
@GetMapping("/send")
public void send(@RequestParam("message") String message) {
log.info("当前时间 {}, 发送信息: {}",new Date().toString(), message);
rabbitTemplate.convertAndSend("X", "XA", "10s延迟"+message);
rabbitTemplate.convertAndSend("X", "XB", "40s延迟"+message);
}
四、消费者
@Slf4j
@Component
public class DeadLetterReceive {
@RabbitListener(queues = "QD")
public void receiveD(Message message, Channel channel) {
String meg = new String(message.getBody());
log.info("死信队列==当前时间{}, 接收到延迟消息{}", new Date().toString(), meg);
}
}
五、优化
将设置消息的延迟时间交给生产者设置,不在消费者中设置
可以在消费者中删除代码
//设置过期时间
arguments.put("x-message-ttl", 10000);
生产者代码改为:
@GetMapping("/sendMsgWithTime")
//发送消息并设置过期时间
public void sendMsgWithTime(@RequestParam("message") String message,
@RequestParam("time") String time) {
log.info("当前时间 {}, 时间为{},发送信息: {}",new Date().toString(),time, message);
rabbitTemplate.convertAndSend("X", "XC",
time+"毫秒延迟"+message, msg->{
//设置发送消息的延迟时长
msg.getMessageProperties().setExpiration(time);
return msg;
});
}