-
死信队列产生背景:
- RabbitMQ 死信队列俗称 备胎队列:消息中间件因为某种原因拒收该消息后,可以转移到私信队列中存放,死信队列也可以有交换机和路由 key 等
-
生产死信队列的原因:
- 消息投递到 MQ 存放,消息已经过期,消费者没有及时获取到我们的消息,消息如果存放到 MQ 服务器中过期之后,会转移到备胎死信队列存放
- 多列达到最大长度(队列已满)
- 消费者消费多次消息失败,就会转义到私信队列中
-
案例:
- 配置类:
@Component public class DeadExchangeConfig {//普通交换机@Value("${boyatop.order.exchange}")private String order_exchange;//普通队列@Value("${boyatop.order.queue}")private String order_queue;//普通队列的 key@Value("${boyatop.order.routingKey}")private String order_rotingKey;//死信交换机@Value("${boyatop.dlx.exchange}")private String dlx_exchange;//死信队列@Value("${boyatop.dlx.queue}")private String dlx_queue;//死信队列的 key@Value("${boyatop.dlx.routingKey}")private String dlx_routingKey;//定义死信交换机@Beanpublic DirectExchange dlxExchange(){return new DirectExchange(dlx_exchange);}//定义死信队列@Beanpublic Queue dlxQueue(){return new Queue(dlx_queue);}//定义普通交换机@Beanpublic DirectExchange orderExchange(){return new DirectExchange(order_exchange);}//定义普通队列@Beanpublic Queue orderQueue(){//订单队列绑定死信交换机Map<String,Object> arguments = new HashMap<>(2);arguments.put("x-dead-letter-exchange",dlx_exchange);arguments.put("x-dead-letter-routing-key",dlx_routingKey);return new Queue(order_queue,true,false,false,arguments); // return QueueBuilder.durable(order_queue).withArguments(arguments).build();}//订单队列绑定交换机@Beanpublic Binding bindingOrderExchange(DirectExchange orderExchange, Queue orderQueue){return BindingBuilder.bind(orderQueue).to(orderExchange).with(order_rotingKey);}//死信队列绑定交换机@Beanpublic Binding bindingDlxExchange(DirectExchange dlxExchange, Queue dlxQueue){return BindingBuilder.bind(dlxQueue).to(dlxExchange).with(dlx_routingKey);}}
- 生产者:
@RestController public class producerService {@Value("${boyatop.order.exchange}")private String orderExchange;@Value("${boyatop.order.routingKey}")private String orderRouTingKey;@AutowiredRabbitTemplate rabbitTemplate;@RequestMapping("/sendMsg")public String send(){String msg = "11111";rabbitTemplate.convertAndSend(orderExchange,orderRouTingKey,msg,message -> {//设置超时时间message.getMessageProperties().setExpiration("5000");return message;});return "success";}}
- yml 文件:
spring:rabbitmq:####连接地址host: 127.0.0.1####端口号port: 5672####账号username: guest####密码password: guest### 地址virtual-host: boyatopVirtualHost#演示死信队列 boyatop:#备胎交换机dlx:exchange: boyatop_dlx_exchangequeue: boyatop_dlx_queueroutingKey: dlx#普通交换机order:exchange: boyatop_order_exchangequeue: boyatop_order_queueroutingKey: order
- 配置类:
-
死信队列架构原理:
- 死信队列和普通队列区别不是很大
- 普通队列和死信队列都有自己独立的交换机、路由 key、队列和消费者
- 区别:
- 生产者投递消息先投递到普通交换机中,普通交换机再将该消息投到普通队列中缓存起来,普通队列对应有自己独立的消费者
- 如果生产者投递消息到普通队列中,普通队列发现该消息一直没有被消费者消费的情况下,这时候会将该消息转移到死信(备胎)交换机中
- 死信(备胎)交换机对应有自己独立的死信(备胎)队列,对应独立的死信(备胎)消费者
-
死信队列应用场景:
- 30 分钟订单超时设计
- redis 过期 key
- 死信延迟队列实现
- 采用死信队列,创建一个普通队列没有对应的消费者消费该消息,在 30 分钟过后就会将该消息转移到死信备胎消费者实现消费
- 死信备胎消费者会根据订单号码查询是否已经支付过,如果没有支付的情况下则会开始回滚库存操作
- 30 分钟订单超时设计