一、死信概述
死信队列产生的背景
-
RabbitMQ死信队列俗称,备胎队列;消息中间件因为某种原因拒收该消息后,可以转移到死信队列中存放,死信队列也可以有交换机和路由key等。
产生死信队列的原因 (前提是设置了死信队列)
-
消息投递到MQ中存放 消息已经过期 消费者没有及时消费,服务器中的消息过期之后,会转移到备胎死信队列存放 / (我们可以根据这个特性去实现例如订单回滚等业务场景)
-
队列达到最大的长度 (队列容器已经满了)
-
消费者消费多次消息失败,就会转移存放到死信队列
死信队列的架构原理
-
死信队列和普通队列区别不是很大
-
普通与死信队列都有自己独立的交换机和路由key、队列和消费者。
二、实现简单demo
· application.yml
spring:
rabbitmq:
host: 127.0.0.1
port: 5672
username: guest
password: guest
virtual-host: /MuPing
#自定义内容
sdkj:
#通常
usual:
exchange_name: usual_exchange
queue_name: usual_queue
#路由key
routingKey: sdkj_usual
#死信
dead:
exchange_name: dead_exchange
queue_name: dead_queue
#路由key
routingKey: sdkj_dead
1.SiXinConfig
1 package com.sdkj.config; 2 3 import org.springframework.amqp.core.Binding; 4 import org.springframework.amqp.core.BindingBuilder; 5 import org.springframework.amqp.core.DirectExchange; 6 import org.springframework.amqp.core.Queue; 7 import org.springframework.beans.factory.annotation.Value; 8 import org.springframework.context.annotation.Bean; 9 import org.springframework.stereotype.Component; 10 11 import java.util.HashMap; 12 import java.util.Map; 13 14 /** 15 * @Author wangshuo 16 * @Date 2022/5/7, 21:34 17 * Please add a comment 18 */ 19 @Component 20 public class SiXinConfig { 21 22 @Value("${sdkj.usual.exchange_name}") 23 private String orderExchange; 24 25 @Value("${sdkj.usual.queue_name}") 26 private String orderQueue; 27 28 /** 29 * 订单路由key 30 */ 31 @Value("${sdkj.usual.routingKey}") 32 private String orderRoutingKey; 33 /** 34 * 死信交换机 35 */ 36 @Value("${sdkj.dead.exchange_name}") 37 private String dlxExchange; 38 39 /** 40 * 死信队列 41 */ 42 @Value("${sdkj.dead.queue_name}") 43 private String dlxQueue; 44 /** 45 * 死信路由 46 */ 47 @Value("${sdkj.dead.routingKey}") 48 private String dlxRoutingKey; 49 50 /** 51 * 声明死信交换机 52 * 53 * @return DirectExchange 54 */ 55 @Bean 56 public DirectExchange dlxExchange() { 57 return new DirectExchange(dlxExchange); 58 } 59 60 /** 61 * 声明死信队列 62 * 63 * @return Queue 64 */ 65 @Bean 66 public Queue dlxQueue() { 67 return new Queue(dlxQueue); 68 } 69 70 /** 71 * 声明订单业务交换机 72 * 73 * @return DirectExchange 74 */ 75 @Bean 76 public DirectExchange orderExchange() { 77 return new DirectExchange(orderExchange); 78 } 79 80 /** 81 * 声明订单队列 82 * 83 * @return Queue 84 */ 85 @Bean 86 public Queue orderQueue() { 87 // 订单队列绑定我们的死信交换机 88 Map<String, Object> arguments = new HashMap<>(2); 89 arguments.put("x-dead-letter-exchange", dlxExchange); 90 arguments.put("x-dead-letter-routing-key", dlxRoutingKey); 91 return new Queue(orderQueue, true, false, false, arguments); 92 } 93 94 /** 95 * 绑定死信队列到死信交换机 96 * 97 * @return Binding 98 */ 99 @Bean 100 public Binding binding() { 101 return BindingBuilder.bind(dlxQueue()) 102 .to(dlxExchange()) 103 .with(dlxRoutingKey); 104 } 105 106 107 /** 108 * 绑定订单队列到订单交换机 109 * 110 * @return Binding 111 */ 112 @Bean 113 public Binding orderBinding() { 114 return BindingBuilder.bind(orderQueue()) 115 .to(orderExchange()) 116 .with(orderRoutingKey); 117 } 118 }
2.OrderProducer
1 package com.sdkj.producer; 2 3 import org.springframework.amqp.rabbit.core.RabbitTemplate; 4 import org.springframework.beans.factory.annotation.Autowired; 5 import org.springframework.beans.factory.annotation.Value; 6 import org.springframework.web.bind.annotation.RequestMapping; 7 import org.springframework.web.bind.annotation.RestController; 8 9 /** 10 * @Author wangshuo 11 * @Date 2022/5/7, 21:46 12 * Please add a comment 13 */ 14 @RestController 15 public class OrderProducer { 16 17 @Autowired 18 private RabbitTemplate rabbitTemplate; 19 /** 20 * 订单交换机 21 */ 22 @Value("${sdkj.usual.exchange_name}") 23 private String orderExchange; 24 /** 25 * 订单路由key 26 */ 27 @Value("${sdkj.usual.routingKey}") 28 private String orderRoutingKey; 29 30 @RequestMapping("/sendOrder") 31 public String sendOrder() { 32 String msg = "哈哈哈"; 33 rabbitTemplate.convertAndSend(orderExchange, orderRoutingKey, msg, message -> { 34 // 设置消息过期时间 10秒过期 35 message.getMessageProperties().setExpiration("10000"); 36 return message; 37 }); 38 return "success"; 39 } 40 }
3.UsualConsumer
1 package com.sdkj.consumer; 2 3 import org.springframework.amqp.rabbit.annotation.RabbitListener; 4 import org.springframework.stereotype.Component; 5 6 /** 7 * @Author wangshuo 8 * @Date 2022/5/7, 21:44 9 * Please add a comment 10 */ 11 @Component 12 public class UsualConsumer { 13 14 /* 15 监听回调方法 16 */ 17 @RabbitListener(queues = "usual_queue") 18 public void orderConsumer(String msg) { 19 System.out.println("正常订单消费者消息MSG: " + msg); 20 } 21 }
4.DeadConsumer
1 package com.sdkj.consumer; 2 3 import org.springframework.amqp.rabbit.annotation.RabbitListener; 4 import org.springframework.stereotype.Component; 5 6 /** 7 * @Author wangshuo 8 * @Date 2022/5/7, 21:44 9 * Please add a comment 10 */ 11 @Component 12 public class DeadConsumer { 13 14 /** 15 * 死信队列监听队列回调的方法 16 * 17 * @param msg 18 */ 19 @RabbitListener(queues = "dead_queue") 20 public void orderConsumer(String msg) { 21 System.out.println("死信队列消费订单消息: " + msg); 22 } 23 }
本文来自博客园,作者:荣慕平,转载请注明原文链接:https://www.cnblogs.com/rongmuping/articles/16244368.html