RabbitMQ 实战:理解“不公平分发(Unfair Dispatching)”机制

作者:sg_knight日期:2025/11/6

一、前言

在使用 RabbitMQ 构建消息队列系统时,很多人都知道它有“轮询分发(Round-Robin Dispatching)”机制。
也就是说:

如果有多个消费者同时订阅同一个队列,RabbitMQ 会尽量让每个消费者轮流接收相同数量的消息。

听起来很“公平”,但实际运行中你可能会发现——
有的消费者几乎“忙不过来”,而另一些消费者却“闲得发慌”。
这,就是所谓的 不公平分发(Unfair Dispatching) 现象。


二、为什么会出现“不公平分发”?

RabbitMQ 默认是按轮询(round-robin)方式推送消息的,并不会实时了解每个消费者的“处理能力”或“忙碌程度”。

举个例子:

  • 有两个消费者:Consumer AConsumer B
  • 队列中有 10 条消息
  • A 每条消息要处理 1 秒
  • B 每条消息要处理 100 毫秒

RabbitMQ 在默认配置下,会:

  • 把第 1 条消息发给 A
  • 把第 2 条消息发给 B
  • 第 3 条再给 A
  • 第 4 条再给 B

最终结果是:

B 很快处理完消息进入空闲状态,而 A 仍在忙碌;
但 RabbitMQ 仍会继续按顺序“公平”分配消息给 A。
久而久之,系统就出现了性能瓶颈——慢的拖慢整体速度


三、核心原因:basicQos 的默认值

在 RabbitMQ 中,每个消费者可以通过设置 预取值(prefetch count) 来控制一次能拿多少消息。
默认情况下,这个值为 0(即不限数量)。

也就是说:

消费者一旦连接成功,RabbitMQ 会持续把消息推送给它,直到队列为空。

于是处理较慢的消费者,就会堆积一堆消息,而处理快的消费者反而得不到新的任务。

这就是“不公平分发”的本质。


四、解决方案:启用“公平分发(Fair Dispatch)”

想要让 RabbitMQ 尽可能“公平”分配消息,需要显式设置 basicQos 参数:

1channel.basicQos(1);
2

这行代码的含义是:

告诉 RabbitMQ:同一时间内,最多只向该消费者推送 1 条未确认消息
当消费者 ack 确认处理完成后,再分发下一条。

这样:

  • 处理快的消费者,会更频繁收到消息;
  • 处理慢的消费者,会自然被“限流”;
  • 消息处理整体更高效。

五、示例对比

(1)不公平分发默认效果:

1channel.basicQos(0); // 默认值,不限制
2

效果:

慢的消费者 backlog 堆积严重,快的消费者闲置。


(2)启用公平分发:

1channel.basicQos(1); // 一次仅分发 1 条未确认消息
2

效果:

RabbitMQ 会动态调节分发速度,整体系统负载更均衡。


六、额外优化:ack 与持久化策略

别忘了配合 手动确认机制(manual ack) 使用,否则 RabbitMQ 无法判断消息是否处理完成。

示例:

1boolean autoAck = false;
2channel.basicConsume(queueName, autoAck, consumer);
3
4consumer.handleDelivery(tag, env, props, body) -> {
5    // 处理业务逻辑
6    ...
7    channel.basicAck(env.getDeliveryTag(), false); // 手动确认
8};
9

这样可以避免消息丢失,同时结合 basicQos(1) 实现真正意义上的“按能力分发”。


七、总结

场景默认行为结果解决方案
多消费者同时监听队列轮询分发快的闲、慢的累设置 basicQos(1)
消费者处理能力差异大消息积压不均系统吞吐下降启用“公平分发”
无手动 ackRabbitMQ 不知道处理状态消息可能丢失使用 basicAck

✅ 建议:对性能要求较高的消费端,务必启用手动确认 + 限制预取值


八、一句话总结

“公平分发”并非 RabbitMQ 的默认行为,
但只需一行代码,就能让你的队列系统更聪明、更高效。


RabbitMQ 实战:理解“不公平分发(Unfair Dispatching)”机制》 是转载文章,点击查看原文


相关推荐


Redis(99)Redis的高可用性如何实现?
Victor3562025/11/2

实现Redis的高可用性是确保系统在硬件故障、网络中断或其他问题发生时依然能够正常运行的重要手段。Redis提供了多种机制来实现高可用性,包括主从复制、哨兵模式和Redis集群。以下是详细的实现步骤和代码示例。 1. 主从复制 主从复制(Master-Slave Replication)是Redis实现高可用性的基础。通过配置多个从节点(Slave),可以在主节点(Master)出问题时继续提供读操作。 配置主从复制 假设有两台机器:主节点 192.168.1.100 和从节点 192.168.


Redis Sentinel哨兵集群
新手小白*2025/10/30

一、Redis主从复制中的问题 Redis主从复制集群可以将主节点的数据改变同步给从节点,这样从节点就可以起到两个作用:第一:作为主节点的一个备份,一旦主节点出了故障不能继续对外提供服务时,从节点可以作为后备"顶"上来,并且保证数据尽量不丢失。第二,从节点可以扩展主节点的读能力,通过实现读写分离结构,可以大大减轻主节点在进行高并发读写操作时的访问压力。 但是主从同步也带了一些问题: 一旦主节点故障,需要手动将一个从节点晋升为主节点,slaveof no one。 需要修改客户端或


Python 的内置函数 enumerate
IMPYLH2025/10/27

Python 内建函数列表 > Python 的内置函数 enumerate Python 的内置函数 enumerate 是一个非常有用的工具函数,主要用于在遍历序列(如列表、元组或字符串)时,同时获取元素的索引和值。 基本语法如下: enumerate(iterable, start=0) 其中: iterable 表示任何可迭代对象start 是可选参数,指定索引的起始值,默认为 0 使用示例: fruits = ['apple', 'banana', 'orange'] f


系统与网络安全------弹性交换网络(5)
virelin_Y.lin2025/10/25

资料整理于网络资料、书本资料、AI,仅供个人学习参考。 VLAN间通信 VLANIF VLANIF虚接口 三层交换机 具备路由功能的交换机,称之为三层交换机或多层交换机 VLAN间通信解决方案 VLANIF虚接口 VLANIF虚接口 每个VLAN都对应一个VLANIF接口 VLANIF接口是一种三层虚拟接口,可以实现VLAN间的三层互通 给每个VLAN需要配置一个VLAN虚接口,配置接口IP地址,作为VLAN内主机的网关地址 VLANIF接口不占用额外的物理端口资


仓颉语言核心技术全解析与实战教程
IT·陈寒2025/10/22

文章目录 语言特性深度解析标准库源码拆解实战项目复盘项目概览项目结构核心实现点 入门基础教程安装 SDK创建第一个项目基础语法 第三方库适配服务端应用开发鸿蒙应用开发性能优化总结与实践建议 博主介绍:全网粉丝10w+、CSDN合伙人、华为云特邀云享专家,阿里云专家博主、星级博主,51cto明日之星,热爱技术和分享、专注于Java技术领域 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇🏻 不然下次找不到哟 语言特性深度解析 仓颉语言是一种面向多端的


[人工智能-大模型-30]:大模型应用层技术栈 - 上下文增强层:谁掌握了更高效、更精准的上下文增强能力,谁就能构建出真正有价值的智能系统。
文火冰糖的硅基工坊2025/10/22

上下文增强层(Context Augmentation)”是一个在人工智能、特别是大语言模型(LLM)应用架构中非常关键的概念。它通常出现在构建智能对话系统、检索增强生成(RAG)系统或企业级AI代理(Agent)的分层设计中。 我们可以将其理解为:在原始用户输入(Query)和模型生成(Generation)之间,一个至关重要的“信息注入”环节。它的核心使命是——让模型在回答问题时,拥有更丰富、更准确、更相关的背景信息,从而提升回答的质量、准确性和实用性。 一、上下文增强层的定位(在系统


【SpringCloud(7)】SpringCloud Config分布式配置中心;服务端与客户端配置;SpringCloud Bus总线;bus刷新全局广播
凉凉心.2025/10/20

1. SpringCloud Config 分布式配置中心 1.1 目前分布式微服务架构的痛点 微服务意味着要将单体应用中的业务拆分成一个个自服务,每个服务的粒度相对较小,因此系统中会出现大量的服务。由于每个服务都需要必要的配置信息才能允许,所以一套集中式的、动态的配置管理设备是必不可少的 SpringCloud提供了ConfigServer来解决这个问题。 1.1 SpringCloud Config是什么? SpringCloud Config为微服务架构中的微服务提供集中化的


Vue 内置组件全解析:提升开发效率的五大神器
90后晨仔2025/10/19

在 Vue 开发中,除了我们日常编写的业务组件外,框架还提供了一系列内置组件,它们为我们处理常见的开发场景提供了优雅的解决方案。今天,我们就来深入探讨 Vue 的五大内置组件:Transition、TransitionGroup、KeepAlive、Teleport 和 Suspense。 1. Transition - 丝滑的过渡动画 什么是 Transition? Transition 组件用于在元素或组件的插入、更新和移除时添加动画效果,让用户体验更加流畅。 基本使用 <template


Java Kubernetes本地部署RuoYi框架jar包
自由的疯2025/10/18

在本地 Kubernetes 集群中部署 RuoYi 框架的 JAR 包是一个很好的实践,可以帮助你更好地理解和掌握 Kubernetes 的应用部署流程。以下是详细的步骤,指导你在本地 Kubernetes 集群中部署 RuoYi 框架的 JAR 包。 1. 准备环境 1.1 安装 Minikube 或 kind 首先,确保你已经安装了 Minikube 或 kind 来本地运行 Kubernetes 集群。这里以 Minikube 为例进行说明。 安装 kubectl: curl -LO


从 Tomcat 与 Jetty 的对比,聊聊影响一个服务并发能力的关键因素
G探险者2025/10/16

大家好,我是G探险者! 在 Java 服务体系中,Tomcat 与 Jetty 是最常见的 Web 容器。很多人认为,只要加大连接数或线程数,就能提升并发能力。 但事实远比想象复杂:连接数只是冰山一角,背后还有线程模型、I/O 模型、内核资源限制等多重因素。 本文从 Tomcat 与 Jetty 的对比 入手,系统讲清楚——到底是什么在决定你的服务并发上限。 🧩 一、Tomcat 与 Jetty 的架构差异 1️⃣ Tomcat 的工作模型 Tomcat 默认采用 多线程 + 阻塞 I/O

首页编辑器站点地图

Copyright © 2025 聚合阅读

License: CC BY-SA 4.0