微服务24_服务异步通信03:RabbitMQ消息堆积解决方法:惰性队列

微服务24_服务异步通信03:消息堆积解决方法:惰性队列

  • 前言:消息队列在使用过程中,面临着很多实际问题需要思考:
  • 本文章是:消息堆积问题:
      • 总结
  • 一、消息堆积问题
    • 1、什么是消息堆积问题:
  • 二、惰性队列来解决消息堆积
    • 1.惰性队列
    • 2、开启惰性队列
      • 1.一个正在运行的普通队列,变成惰性队列
      • 2. 申明一个全新的队列,配置为惰性队列
    • 3、测试:

前言:消息队列在使用过程中,面临着很多实际问题需要思考:

  1. 消息可靠性问题:确保发送的消息至少被消费一次。当发送消息后,MQ一定保证投递到消费者,而且被消费掉。
  2. 延迟消息的问题:实现消息的延迟投递。业务需求,例如BOSS预约腾讯会议,半个小时后通知所有的人。
  3. 消息堆积问题:如何解决数百万消息堆积,无法及时消费的问题。。例如在高并发场景下,消息的发送越来越多,消费者忙不过来。那么MQ能否保存数百万的消息。
  4. 高可用问题:应避免单点的MQ故障,避免不可以问题。单机模式,一旦出现故障,整个服务就不用了。搭建集群、集群同步、集群通信。
    在这里插入图片描述

第一节:消息可靠性问题
第二节:延迟消息问题
第三节:消息堆积问题
第四节:高可用问题:普通、镜像、仲裁集群

本文章是:消息堆积问题:

总结

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

  • 队列上绑定多个消费者,提高消费速度
  • 使用惰性队列,可以再mq中保存更多消息

惰性队列的优点有哪些?

  • 基于磁盘存储,消息上限高
  • 没有间歇性的page-out,性能比较稳定

惰性队列的缺点有哪些?

  • 基于磁盘存储,消息时效性会降低
  • 性能受限于磁盘的IO

一、消息堆积问题

1、什么是消息堆积问题:

当生产者发送消息的速度超过了,消费者处理消息的速度,就会导致队列中的消息堆积,直到队列存储消息达到上限。 最早进入队列中的消息,可能称为死信,会被丢弃,这就是消息堆积问题。
微服务24_服务异步通信03:RabbitMQ消息堆积解决方法:惰性队列_第1张图片

可能发送丢弃现象,在对于消息的安全性较高的业务当中,不可以接受的。那么有什么办法能解决消息堆积的问题吗?

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

  1. 增加更多消费者,提高消费速度【增加消费者】
  2. 在消费者内开启线程池,加快消费者消息处理速度【消费者加线程池】
    • 优点: 有消息来了以后,交给线程来处理,从而提高消费者的处理能力。
    • 缺点:开启线程池来加快消息处理,消息很多那么就得开启很多线程,线程越多是对CPU的一种浪费。因为CPU会在多个线程之间进行上下文切换。
    • 适合的业务:消息处理的业务耗时比较长的情况,CPU就可以并行处理多个业务
  3. 扩大队列容积,提高队列上限【队列角度:缓解堆积问题】

二、惰性队列来解决消息堆积

扩大队列容积,就是说提高队列存储消息量的上限。队列中的消息是存储到内存当中的,那么在高并发的场景下,消息量非常大, 高达数百万,如果都放在内存当中,显然是不合适的。 那么惰性队列如何解决这件事呢?

1.惰性队列

对于传统的队列,如果没有开启持久化,那么会把消息放到内存当中,目的是为了加快投递速度。拿和取都是通过内存,所以速度非常快。
但是在内存当中存储是有上限的,MQ会设定预警值,默认为百分之四十,当发生消息堆积时,很有可能达到预警值,此时MQ就会处于一个暂停状态,阻止生产者的消息投递进来,从而会把内存部分消息放入到磁盘,这个动作叫做:page out。
所以会导致MQ有一个阶段性的暂停状态(阻止用户写入请求),那么MQ的并发能力出现波浪性的忽高忽低情况。从而性能不稳定

从RabbitMQ的3.6.0版本卡死,就增加了Lazy Queues的概念,也就是惰性队列
惰性队列的特征:

  1. 接收到消息后直接存入磁盘,而非内存
  2. 消费者取消息时,才会从磁盘中读取并加载到内存
  3. 支持数百万条的消息存储。

对于Lazy Queue直接写入磁盘,所以很难触发MQ的预警值,从而不会出现page Out问题的出现,从而性能会比较稳定。
问题:写入磁盘,会带入一定的读写延迟(可接受的范围内)
适合场景:消息堆积问题

2、开启惰性队列

1.一个正在运行的普通队列,变成惰性队列

而要设置一个队列为惰性队列,只需要在声明队列时,指定x-queue-mode属性为lazy即可。可以通过命令行将一个运行中的队列修改为惰性队列:

rabbitmqctl set_policy Lazy "^lazy-queue$" '{"queue-mode":"lazy"}' --apply-to queues  

命令解读:

  • rabbitmqctl :RabbitMQ的命令行工具。提供的控制台功能
  • set_policy :添加一个策略
  • Lazy :策略名称,可以自定义
  • "^lazy-queue$" :用正则表达式匹配队列的名字
  • '{"queue-mode":"lazy"}' :设置队列模式为lazy模式
  • --apply-to queues :策略的作用对象,是所有的队列

2. 申明一个全新的队列,配置为惰性队列

微服务24_服务异步通信03:RabbitMQ消息堆积解决方法:惰性队列_第2张图片
微服务24_服务异步通信03:RabbitMQ消息堆积解决方法:惰性队列_第3张图片

3、测试:

创建一个lazy模式的队列、创建一个普通队列

创建一个test直接发送到队列中的消息

查看lazy模式:
微服务24_服务异步通信03:RabbitMQ消息堆积解决方法:惰性队列_第4张图片

查看普通模式:
在波动,每当到达预警值时,就会先暂停接受数据,然后把数据刷到内存中。
稳定性不好
微服务24_服务异步通信03:RabbitMQ消息堆积解决方法:惰性队列_第5张图片

你可能感兴趣的:(微服务技术栈,rabbitmq)