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

一、前言

在使用 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 参数:

channel.basicQos(1);

这行代码的含义是:

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

这样:

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






次阅读

扫描下方二维码,关注公众号:程序进阶之路,实时获取更多优质文章推送。


扫码关注

评论