介绍
1、什么是死信队列
- 没有及时消费的消息存放的队列
2、死信队列和延时队列配置使用场景
- 超时未支付订单处理,30分钟未支付自动取消订单。
- 淘宝中的七天自动确认收货,自动评价。
<!--rabbitmq-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.0.1-jre</version>
</dependency>
Rabbit延时队列样例
1、在配置类中创建和配置好死信交换机、死信队列、普通交换机、普通队列
package com.lezu.springboot.configuration.rabbitmq;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
/**
* @author LianJiaYu
* @date 2022/8/30 10:01
*/
@Configuration
public class DeadExchangeConfig {
// 死信交换机
public static final String DEAD_LETTER_EXCHANGE = "dead_letter_exchange1";
// 死信队列
public static final String DEAD_MERCHANT_DEAD_QUEUE = "DEAD_merchant_dead_queue1";
// 进入死信队列的路由key
public static final String DEAD_MERCHANT_DEAD_ROUTING_KEY = "DEAD_merchant_dead_routing_key1";
//创建死信交换机
@Bean
public DirectExchange deadLetterExchange1() {
return new DirectExchange(DEAD_LETTER_EXCHANGE);
}
//创建死信队列,用来处理死信队列中10秒后的数据
@Bean
public Queue deadQueueHandle1() {
return new Queue(DEAD_MERCHANT_DEAD_QUEUE);
}
//绑定死信交换机和死信队列
@Bean
public Binding deadQueueHandleBinding1() {
return BindingBuilder
.bind(deadQueueHandle1())
.to(deadLetterExchange1())
.with(DEAD_MERCHANT_DEAD_ROUTING_KEY);
}
//*********************************分割线*********************************
// 普通交换机(延时队列交换机)
public static final String DELAY_LETTER_EXCHANGE = "delay_letter_exchange1";
// 普通队列
public static final String NEW_MERCHANT_QUEUE = "new_merchant_queue1";
// 进入普通队列的路由key
public static final String NEW_MERCHANT_ROUTING_KEY = "new_merchant_routing_key1";
//创建普通交换机(延迟队列交换机)
@Bean
public DirectExchange delayExchange1() {
return new DirectExchange(DELAY_LETTER_EXCHANGE);
}
//创建普通队列 (这里普通队列绑定死信交换机配置以及死信配置是关键)
@Bean
public Queue delayQueue1() {
HashMap<String, Object> hashMap = new HashMap<>(4);
// 声明死信队列交换机
hashMap.put("x-dead-letter-exchange", DEAD_LETTER_EXCHANGE);
// 声明绑定当前死信路由key
hashMap.put("x-dead-letter-routing-key", DEAD_MERCHANT_DEAD_ROUTING_KEY);
//声明队列的ttl 10秒后自动失效
hashMap.put("x-message-ttl", 1000 * 10);
return QueueBuilder.durable(NEW_MERCHANT_QUEUE).withArguments(hashMap).build();
}
//普通队列 和 普通交换机(延迟队列交换机) 和 普通队列的路由key 一起绑定
@Bean
public Binding newMerchantDeadQueueBinding1() {
return BindingBuilder
.bind(delayQueue1())
.to(delayExchange1())
.with(NEW_MERCHANT_ROUTING_KEY);
}
}
2、添加测试接口
package com.lezu.springboot.rabbitmq.producer;
import com.lezu.springboot.configuration.rabbitmq.DeadExchangeConfig;
import com.lezu.springboot.configuration.rabbitmq.DeadExchangeConfigTwo;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
/**
* @author LianJiaYu
* @date 2022/8/30 10:19
*/
@RestController
@RequestMapping("/api/admin/merchant")
public class DeadController {
@Autowired
private RabbitTemplate rabbitTemplate;
/**
* http://localhost:8080/api/admin/merchant/sendMsg1/我是sendMsg1
* 消息先进入普通队列,10秒之后进入死信队列
* @param msg
* @return
*/
@RequestMapping("/sendMsg1/{msg}")
public Object sendMsg1(@PathVariable("msg") String msg) {
//发送延时消息
rabbitTemplate.convertAndSend(DeadExchangeConfig.DELAY_LETTER_EXCHANGE, DeadExchangeConfig.NEW_MERCHANT_ROUTING_KEY, msg + "------dead");
Map<String,String> hashMap = Maps.newHashMapWithExpectedSize(2);
hashMap.put("code", "200");
hashMap.put("msg", "请在10秒内完成该操作~");
return hashMap;
}
}
3、消息监听和消费(10秒钟后才能拿到消息进行消费)
package com.lezu.springboot.rabbitmq.consumer;
import com.lezu.springboot.configuration.rabbitmq.DeadExchangeConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* @author LianJiaYu
* @date 2022/8/30 10:22
*/
@Slf4j
@Component
public class DeadQueueListener {
@RabbitListener(queues = DeadExchangeConfig.DEAD_MERCHANT_DEAD_QUEUE)
public void messageHandler1(String testMessage) {
System.out.println("DeadQueueListener消费者收到消息1 : " + testMessage);
//执行业务逻辑代码
// .....此处省略
}
}