当前位置:   article > 正文

RabbitMQ消息堆积问题

rabbitmq消息堆积

当生产者发送消息的速度超过了消费者处理消息的速度,就会导致队列中的消息堆积,直到队列存储消息达到上限。最早接收到的消息,可能就会成为死信,会被丢弃,这就是消息堆积问题。

解决消息堆积有三种思路:

  1. 增加更多消费者,提高消费速度

  2. 在消费者内开启线程池加快消息处理速度

  3. 扩大队列容积,提高堆积上限

1、惰性队列

上面呢,我们已经 知道解决消息队列的常见三种解决方案,其中一种方案就是想办法去提高一个队列它能存储一个消息量的上限。

但是RabbitMQ呢是内存存储的,如果说在高并发的情况下消息量非常的大,这些消息我们如果都给它丢到内存当中,显然是不合适的,所以我们就要学习一个惰性队列来解决这个问题!

RabbitMQ3.6.0版本开始,就增加了Lazy Queues的概念,也就是惰性队列。惰性队列的特征如下:

  1. 接收到消息后直接存入磁盘而非内存

  2. 消费者要消费消息时才会从磁盘中读取并加载到内存

  3. 支持数百万条的消息存储

1.1 基于@Bean声明lazy-queue

  1. package com.jie.mq.config;
  2. import org.springframework.amqp.core.Queue;
  3. import org.springframework.amqp.core.QueueBuilder;
  4. import org.springframework.context.annotation.Bean;
  5. import org.springframework.context.annotation.Configuration;
  6. @Configuration
  7. public class LazyConfig {
  8. /**
  9. * @description:惰性队列
  10. * @author: jie
  11. * @time: 2022/3/13 11:06
  12. */
  13. @Bean
  14. public Queue lazyQueue(){
  15. return QueueBuilder.durable("lazy.queue")
  16. .lazy()
  17. .build();
  18. }
  19. /**
  20. * @description:普通队列
  21. * @author: jie
  22. * @time: 2022/3/13 11:06
  23. */
  24. @Bean
  25. public Queue normalQueue(){
  26. return QueueBuilder.durable("normal.queue")
  27. .build();
  28. }
  29. }

运行,查看浏览器。

1.2 基于@RabbitListener声明LazyQueue

  1. /**
  2. * @description:声明惰性队列
  3. * @author: jie
  4. * @time: 2022/3/13 14:37
  5. */
  6. @RabbitListener(queuesToDeclare = @Queue(
  7. name = "lazy.queue",
  8. durable = "true",
  9. arguments = @Argument(name = "x-queue-mode",value = "lazy")
  10. ))
  11. public void listenLazyQueue(String msg){
  12. System.out.println("消费者接收到simple.queue的消息:【" + msg + "】");
  13. }

1.3 发送消息

  1. package com.jie.mq.spring;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.junit.Test;
  4. import org.junit.runner.RunWith;
  5. import org.springframework.amqp.core.Message;
  6. import org.springframework.amqp.core.MessageBuilder;
  7. import org.springframework.amqp.core.MessageDeliveryMode;
  8. import org.springframework.amqp.rabbit.core.RabbitTemplate;
  9. import org.springframework.beans.factory.annotation.Autowired;
  10. import org.springframework.boot.test.context.SpringBootTest;
  11. import org.springframework.test.context.junit4.SpringRunner;
  12. import java.nio.charset.StandardCharsets;
  13. @Slf4j
  14. @RunWith(SpringRunner.class)
  15. @SpringBootTest
  16. public class SpringAmqpTest {
  17. @Autowired
  18. private RabbitTemplate rabbitTemplate;
  19. @Test
  20. public void testLazyQueue() throws InterruptedException {
  21. for (int i = 0; i < 1000000; i++) {
  22. String routingKey = "delay";
  23. //1、准备消息
  24. Message message = MessageBuilder
  25. .withBody("hell,Spring".getBytes(StandardCharsets.UTF_8))
  26. .setDeliveryMode(MessageDeliveryMode.NON_PERSISTENT)
  27. .build();
  28. //2、发送消息
  29. rabbitTemplate.convertAndSend("lazy.queue", message);
  30. }
  31. }
  32. @Test
  33. public void testNormaQueue() throws InterruptedException {
  34. for (int i = 0; i < 1000000; i++) {
  35. String routingKey = "delay";
  36. //1、准备消息
  37. Message message = MessageBuilder
  38. .withBody("hell,Spring".getBytes(StandardCharsets.UTF_8))
  39. .setDeliveryMode(MessageDeliveryMode.NON_PERSISTENT)
  40. .build();
  41. //2、发送消息
  42. rabbitTemplate.convertAndSend("normal.queue", message);
  43. }
  44. }
  45. }

2、总结

消息堆积问题的解决方案?

  1. 队列上绑定多个消费者,提高消费速度

  2. 使用惰性队列,可以再mq中保存更多消息

惰性队列的优点有哪些?

  1. 基于磁盘存储,消息上限高

  2. 没有间歇性的page-out,性能比较稳定

惰性队列的缺点有哪些?

  1. 基于磁盘存储,消息时效性会降低

  2. 性能受限于磁盘的IO

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/546300
推荐阅读
相关标签
  

闽ICP备14008679号