RabbitMQ-----死信队列
消息成为死信的三种情况
- 队列长度达到限制
- 消费者拒绝消费消息,basicNack/basicReject,并且不把消息重回队列
- 源队列存在消息过期限制,消息超时未消费
总结了以下两种配置
第一种配置,所有参数都放在map里面,map里的key可以看RabbirMQ中queue的Arguments参数
@Configuration
public class RabbitMQConfig {
/**
* 正常交换机的名称
*/
public static final String TOPIC_EXCHANGE_BOOT = "direct_exchange-boot";
/**
* s信交换机的名称
*/
public static final String DLX_EXCHANGE_BOOT = "dlx_exchange-boot";
/**
* 正常队列的名称
*/
public static final String TOPIC_QUEUE1_BOOT = "direct_queue1";
/**
* s信队列的名称
*/
public static final String DLX_QUEUE1_BOOT = "dlx_queue1";
/**
* 声明队列
*
* @return
*/
@Bean("itemqueue")
public Queue queueDeclare() {
Map<String, Object> args = new HashMap<>(2);
// x-dead-letter-exchange
args.put("x-dead-letter-exchange", DLX_EXCHANGE_BOOT);
// x-dead-letter-routing-key
args.put("x-dead-letter-routing-key", DLX_QUEUE1_BOOT);
//x-message-ttl
args.put("x-message-ttl", 9000);
//x-max-length
args.put("x-max-length", 99);
return QueueBuilder.durable(TOPIC_QUEUE1_BOOT).withArguments(args).build();
}
/**
* 声明死信队列
*
* @return
*/
@Bean("dlxqueue")
public Queue queueDlx() {
return QueueBuilder.durable(DLX_QUEUE1_BOOT).build();
}
/**
* 声明s信交换机
*
* @return
*/
@Bean("dlxexchange")
public Exchange exchangeDlx() {
//return ExchangeBuilder.topicExchange(TOPIC_EXCHANGE_BOOT).durable(true).build();
return ExchangeBuilder.directExchange(DLX_EXCHANGE_BOOT).durable(true).build();
}
/**
* 声明正常的交换机
*
* @return
*/
@Bean("exchange")
public Exchange exchangetopic() {
//return ExchangeBuilder.topicExchange(TOPIC_EXCHANGE_BOOT).durable(true).build();
return ExchangeBuilder.directExchange(TOPIC_EXCHANGE_BOOT).durable(true).build();
}
/**
* 队列绑定交换机
*
* @param queue
* @param exchange
* @return
*/
@Bean
public Binding queueBindExchange(@Qualifier("itemqueue") Queue queue, @Qualifier("exchange") Exchange exchange) {
//return BindingBuilder.bind(queue).to(exchange).with("item.#").noargs();
return BindingBuilder.bind(queue).to(exchange).with("direct_queue1").noargs();
}
/**
* s信队列绑定s信交换机
*
* @param queue
* @param exchange
* @return
*/
@Bean
public Binding dlxQueueBindDlxExchange(@Qualifier("dlxqueue") Queue queue, @Qualifier("dlxexchange") Exchange exchange) {
//return BindingBuilder.bind(queue).to(exchange).with("item.#").noargs();
return BindingBuilder.bind(queue).to(exchange).with("dlx_queue1").noargs();
}
}
第二种配置,ttl配置在生产者中
MessagePostProcessor messagePostProcessor=message -> {
MessageProperties messageProperties = message.getMessageProperties();
//设置编码
messageProperties.setContentEncoding("utf-8");
//设置过期时间10*1000毫秒
messageProperties.setExpiration("5000");
return message;
};
流程
生产者
@RunWith(SpringRunner.class)
@SpringBootTest
public class RabbitMQTest {
@Autowired
private RabbitTemplate rabbitTemplate;
@Test
public void test(){
for (int i = 0; i < 10000; i++) {
/*MessagePostProcessor messagePostProcessor=message -> {
MessageProperties messageProperties = message.getMessageProperties();
// 设置编码
messageProperties.setContentEncoding("utf-8");
// 设置过期时间10*1000毫秒
messageProperties.setExpiration("5000");
return message;
};*/
rabbitTemplate.convertAndSend(RabbitMQConfig.TOPIC_EXCHANGE_BOOT,
"direct_queue1", i+"");
}
}
}
消费者
@Component
@RabbitListener(queues = "dlx_queue1")
public class MyListen {
@RabbitHandler
public void getMessage(String msg, Channel channel, Message message) throws IOException {
System.out.println("接受到的消息:"+msg);
channel.basicNack(message.getMessageProperties().getDeliveryTag(), false,false);
}
}
延迟队列
延迟队列故名思议:即消息进去队列后并不是立即被消费,而是到达某一时间后,才会被消费,其实RabbitMQ中并没有延迟队列,其本质是借助ttl和死信队列结合构成与延迟队列一样的效果