You need to enable JavaScript to run this app.
文档中心
消息队列 RabbitMQ版

消息队列 RabbitMQ版

复制全文
下载 pdf
最佳实践
RabbitMQ 堆积数据过多处理实践
复制全文
下载 pdf
RabbitMQ 堆积数据过多处理实践
在实际使用过程中,RabbitMQ 实例的消息消费能力可能跟不上生产能力,或者消息先生产堆积再消费等场景下,可能会有很多消息堆积在 RabbitMQ 实例里面,导致集群内存、磁盘达到高水位,阻塞消息的生产和消费。​
使用惰性队列​
应用场景​
如果对数据的延迟不是特别敏感,可以使用惰性队列,惰性队列的数据默认会直接写入到磁盘,只有消费者在实际消费时才会从磁盘加载到内存,所以惰性队列既能保证数据的可靠性,而且也会加快节点的重启速度。​
目前,RabbitMQ 3.8 版本实例需要用户手动配置惰性策略,3.12 版本实例默认都是惰性队列,不需要用户配置。所以在申请实例时,优先推荐选择 3.12 版本。​
配置示例​
RabbitMQ 3.8 版本实例手动配置惰性队列如下图所示。​
​​​
使用更小的 QoS​
应用场景​
由于 RabbitMQ 已经堆积了很多消息,这时如果为了加快消费速度,将消费者的 QoS 取值设置较大。但是大量拉取消息到客户端消费,可能会出现消息未及时确认,堆积在 RabbitMQ 内存里面导致内存溢出。所以,在堆积数据量很大的情况,建议使用更小的 QoS,逐渐消费降低堆积。​
配置示例​
以下示例将 RabbitMQ 实例中消费者的 QoS 取值设置为 5。​
说明​
在连接数和通道数都较少的情况下,可以考虑适当提高 QoS 取值。​
​
channel.basicQos(5); ​
​
消费超时设置​
应用场景​
目前火山引擎消息队列 RabbitMQ版实例默认的消费超时时间是 5 分钟,不建议设置过大,因为如果遇到消费异常,可能会出现消费一直被卡住,导致消息堆积上涨的问题。​
配置示例​
​​​
避免一次启动大量连接和通道​
在 RabbitMQ 消息消费大量堆积的情况下,应避免一次性启动大量(约 10000 个)的连接和通道,否则可能出现同一时间从 RabbitMQ 读取大量的消息到内存,从而导致 RabbitMQ 内存溢出。​
监控告警​
应用场景​
为了避免 RabbitMQ 出现消息消费大量堆积,导致业务受损的情况,您可以配置消息队列 RabbitMQ版相关指标的云监控告警规则。​
配置示例​
实例维度​
  • 可消费消息数​
  • 消费堆积如果一直上涨,且堆积的量比较大,则需要关注告警​
  • 未ACK消息量​
  • 主要针对消息已经从rabbitmq 服务端拉取,但是consumer 未ack,消息一直堆积在rabbitmq 内存里面​
节点维度​
  • 内存高水位​
  • 内存高水位出现时,业务的生产和消费可能会被阻塞。​
  • 磁盘高水位​
  • 磁盘高水位出现时,业务的生产和消费可能会被阻塞。​
具体告警规则配置详情请参考推荐配置的告警规则。​
配置消息 TTL​
应用场景​
在 RabbitMQ 3.12 版本中,如果业务消息不是特别重要,可以配置消息的 TTL 参数(仅针对 3.12 版本)。配置后,超过一定时间未消费的消息将被自动过期清理,从而保证集群资源的水位稳定。​
配置示例​
RabbitMQ 3.12 版本配置消息 TTL 参数如下图所示。​
​​​
配置队列 TTL​
应用场景​
如果实例内存使用过多,或者频繁出现内存高水位,建议及时清理历史不活跃的队列。对于已经不再使用的队列,可以手动执行清理(purge data)或直接删除,如果希望系统自动回收,也可以为队列配置自动删除 TTL,使长时间不活跃的队列在满足条件后自动删除,避免持续占用内存资源。​
配置示例​
您可以通过以下两种方式配置。更多信息,请参见 Queue TTL。​
  • 方式一:通过 Policy 配置​
  • 通过expires参数设置过期时间(单位为毫秒)。以下命令将所有队列的过期时间设置为 30 分钟,队列超过该时间未被使用后将自动删除。​
  • ​
    rabbitmqctl set_policy expiry ".*" '{"expires":1800000}' --apply-to queues​
    ​
  • 方式二:通过 x-arguments 配置​
  • 通过x-expires参数设置过期时间(单位为毫秒)。以下示例将队列的过期时间设置为 30 分钟,队列超过该时间未被使用后将自动删除。​
  • ​
    Map<String, Object> args = new HashMap<String, Object>();​
    args.put("x-expires", 1800000);​
    channel.queueDeclare("myqueue", false, false, false, args);​
    ​
Mirror Queue​
注意​
由于存在消息丢失的风险,请尽量避免使用 Mirror Queue。​
如果对经典队列配置了镜像,镜像队列会在所有副本同时非正常下线后将本地数据清空再全量同步,从而引发整个队列消息丢失。所以在镜像队列消息消费已经大量堆积的情况下,应尽量不要再启动过多消费,避免消息消费堆积过多,从而使多个节点同时内存溢出,导致节点非正常下线。​
​
最近更新时间:2026.08.26 14:03:53
这个页面对您有帮助吗?
有用
有用
无用
无用