目录
引入消息堆积问题
场景:当生产者发送消息的速度>消费者处理速度,那么就会导致消息堆积,当储存达到达上限就会引发死信问题,消息变为死信就会被丢弃到死信队列中,这样是很不友好的;
(30条消息) MQ-消息延迟_Fairy要carry的博客-CSDN博客
解决:
从消费者的角度
1.增加更多消费者,增加消费速度(也就是WorkQueue模式,多个消费者绑定一个队列)
(30条消息) SpringAMQP_Fairy要carry的博客-CSDN博客
2.在消费者中开启线程池增加处理速度(但是消耗CPU资源,适合那种耗时较长的任务)
从生产者角度
1.扩大我们的队列的容积,起到一个缓解的作用
惰性队列
典型的以空间换时间的
持久化消息与惰性的区别
持久化:
Bean:QueueBuilder.durable("队列名称")
//队列
@Bean
public Queue ttlQueue() {
return QueueBuilder
.durable("ttl.queue")
//10s后消息变成死信
.ttl(10000)
.deadLetterExchange("dl.direct")
.deadLetterRoutingKey("dl").build();
}
基于注解:
/**
* 消费者监听死信队列,延迟监听
*/
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = "dl.queue", durable = "true"),
exchange = @Exchange(name = "dl.direct"),
key = "dl"
))
public void listenDlQueue(){
log.info("消费者收到了dl.queue的延迟消息");
}
惰性:
@Bean
public Queue LazyQueue(){
return QueueBuilder.durable("lazy.queue")
.lazy()
.build();
}
特征:
1.我们队列接收到消息后直接存入磁盘,而非内存,这样读写速度较慢
2.支持百万数据存储
3.消费者消费消息时从磁盘中读取加载到内存中,速度受到影响
做法:
1.用SpringAMQP声明惰性队列:
消费者启动后:
2.生产者发送消息
/**
* 测试惰性队列的消息发送
*/
@Test
public void testLazyQueue(){
for (int i = 0; i < 1000000; i++) {
Message message = MessageBuilder.withBody("hello,Fairy".getBytes(StandardCharsets.UTF_8))
//不持久化
.setDeliveryMode(MessageDeliveryMode.NON_PERSISTENT)
.build();
rabbitTemplate.convertAndSend("lazy.queue",message);
}
}
/**
* 测试普通队列
*/
@Test
public void testNormalQueue(){
for (int i = 0; i < 1000000; i++) {
Message message = MessageBuilder.withBody("hello,Fairy".getBytes(StandardCharsets.UTF_8))
.setDeliveryMode(MessageDeliveryMode.NON_PERSISTENT)
.build();
rabbitTemplate.convertAndSend("normal.queue",message);
}
}
}
3.生产者发送消息发现消息全被刷到磁盘上(直接硬盘,性能较稳定)
4.普通队列就是在内存上,当占用30%,就会被刷到硬盘,会暂停一下
总结