消息堆积问题
- 当生产者发送消息的速度,超过了消费者处理消息的速度,就会导致队列中的消息堆积,直到队列存储消息达到上限。导致之后发送的消息就会成为死信,可能会被丢弃,这就是消息堆积问题。
解决方案
- 解决消息堆积的两种思路
- 增加更多消费者,提高消费速度。也就是
work queue
模式
- 扩大队列容积,提高堆积上限
- 上面2种方式,都需要加机器、加内存,需要花钱要成本,那么可不可以不花钱,利用起我们的磁盘空间呢?
- 注意:提升队列容积,把消息保存在内存中,消息一多,内存很容易就满了,这显然是不行的,我们可以考虑存到磁盘中,存磁盘的缺点就是慢
惰性队列
- 从RabbitMQ的3.6.0版本开始,就增加了
Lazy Queues
的概念,也就是惰性队列
- 惰性队列有以下特征
- 接收到消息后,直接存入磁盘而非内存
- 消费者要消费消息时,才会从磁盘中读取并加载到内存
- 支持数百万条的消息存储
声明惰性队列
命令行的方式
rabbitmqctl set_policy Lazy "^simple.queue$" '{"queue-mode":"lazy"}' --apply-to queues
- 命令解读
-
rabbitmqctl
:RabbitMQ的命令行工具
-
set_policy
:添加一个策略
-
Lazy
:策略名称,可以自定义
-
"^lazy-queue$"
:用正则表达式匹配队列的名字
-
'{"queue-mode":"lazy"}'
:设置队列模式为lazy模式
-
--apply-to queues
:策略的作用对象,是所有的队列
Java代码的方式
- 方案一:通过
@Bean
方式声明队列,配置lazy
属性
@Bean
public Queue lazyQueue() {
return QueueBuilder
.durable("lazy.queue")
// 开启x-queue-mode,并设置为lazy
.lazy()
.builder();
}
- 方案二:通过
@RabbitListener
,配置x-queue-mode
参数,并指明参数值为lazy
@RabbitListener(queueToDeclare = @Queue(
name = "lazy.queue",
durable = "true",
arguments = @Argument(name="x-queue-mode",value ="lazy" )
))
public void listenLazyQueue(String msg){
log.info("接收到 lazy.queue的消息:{}", msg);
}
总结
- 消息堆积问题的解决方案?
- 队列上绑定多个消费者,提高消费速度
- 使用惰性队列,可以在mq中保存更多消息
- 惰性队列的优点有哪些?
- 基于磁盘存储,消息上限高
- 没有间歇性的page-out(内存到硬盘),性能比较稳定
- 惰性队列的缺点有哪些?
- 基于磁盘存储,消息时效性会降低
- 性能受限于磁盘的IO
网友评论