目录
1. 死信队列(延迟队列)
死信,在官网中对应的单词为“Dead Letter”,它是 RabbitMQ 的一种消息机制。
般来说,生产者将消息投递到 broker 或者直接到 queue 里了,consumer 从 queue 取出消息进行消费,如果它一直无法消费某条数据,那么可以把这条消息放入死信队列里面。等待 条件满足了再从死信队列中取出来再次消费,从而避免消息丢失。
死信消息来源:
- 消息 TTL 过期
- 队列满了,无法再次添加数据
- 消息被拒绝(reject 或 nack),并且 requeue =false
2. 死信队列(延迟队列) 实战
provider(生产者)
-
DeadConfig
package com.jmh.provider.config;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
/**
* @author 蒋明辉
* @data 2022/11/27 9:27
*/
@Configuration
@SuppressWarnings("all")
public class DeadConfig {
/**
* 创建队列
*/
@Bean
public Queue normalQueue(){
Map<String,Object> config=new HashMap<>();
config.put("x-message-ttl", 10000);//message在该队列queue的存活时间最大为10秒
config.put("x-dead-letter-exchange", "deadExchange"); //x-dead-letter-exchange参数是设置该队列的死信交换器(DLX)
config.put("x-dead-letter-routing-key", "BBB");//x-dead-letter-routing-key参数是给这个DLX指定路由键
return new Queue("normalQueue",true,false,false,config);
}
//死信
@Bean
public Queue deadQueue(){
return new Queue("deadQueue");
}
/**
* 创建交换机
*/
@Bean
public DirectExchange normalExchange(){
return new DirectExchange("normalExchange");
}
//死信
@Bean
public DirectExchange deadExchange(){
return new DirectExchange("deadExchange");
}
/**
* 队列和交换机绑定
*/
@Bean
public Binding ormalBinding(){
return BindingBuilder.bind(normalQueue()).to(normalExchange()).with("AAA");
}
//死信
@Bean
public Binding deadBinding(){
return BindingBuilder.bind(deadQueue()).to(deadExchange()).with("BBB");
}
}
- controller
package com.jmh.provider.controller;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author 蒋明辉
* @data 2022/11/25 19:08
*/
@RestController
@SuppressWarnings("all")
public class ProviderController {
@Autowired
private RabbitTemplate rabbitTemplate;
/**
* 死信交换机
* @param key
* @return
*/
@RequestMapping("/deadSend")
public String deadSend(String key){
rabbitTemplate.convertAndSend("normalExchange",key,"order-18526447555220555");
return "yes";
}
}
consumer(消费者)
-
DeadReceiver
package com.jmh.consumer.listener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* @author 蒋明辉
* @data 2022/11/25 19:12
*/
@Component
@SuppressWarnings("all")
@RabbitListener(queues = "deadQueue")
@Slf4j
public class DeadReceiver {
@RabbitHandler
public void info(String msg){
log.info("该订单"+msg+"已经过期");
}
}