[rabbitmq-discuss] High CPU Usage

Matthew Sackman matthew at lshift.net
Wed Jan 6 11:16:51 GMT 2010


Hi Bryan,

On Wed, Dec 30, 2009 at 05:25:57PM -0600, Bryan Murphy wrote:
> I want to set up 3 queues, High, Medium, and Low where I always pull
> messages from the higher priority queues first.  Right now, I more or less
> do the following:
> 
> while (true)
> {
>   result = null;
> 
>   foreach (var queue in queues)
>   {
>     result = model.BasicGet(queue, false);
> 
>     if (result != null)
>       break;
>   }
> 
>   if (result != null)
>     DoSomething(result);
> 
>   Thread.Sleep(15); // 15ms
> }
> 
> Functionally this achieves what I'm trying to accomplish, however, the CPU
> usage of the RabbitMQ server goes through the roof once I spin up a few
> listeners.

Hmmm. Which version of Rabbit are you using. I've just done some maths
and this loop may be doing about 143 calls to basic.get per second
(assuming 2ms for each basic.get). I'm just wondering whether you're
using a version before 1.7.0 in which the queues are hibernating and
thawing too frequently, thus burning up a lot of CPU. On the other hand,
if this was the case, then I'd expect adding more listeners would
improve the situation, not make it worse.

> Is there another way I can accomplish the same thing that doesn't hit the
> RabbitMQ server so hard?

Yes. 3 channels, each one consumes from 1 queue. Then (assuming you're
using the Java client), use the QueueingConsumer, and translate your
foreach to the nextDelivery with a timeout of 0. Also set qos.prefetch
to 1.

Thus the logic is effectively pushed client side.

However, this is not quite the same. With this version, each listener
would buffer up to 1 message from the high queue, 1 from the medium
queue and 1 from the low queue. Thus some other listener could come
along, find that there are no messages at all to process, because
they're currently being buffered by the other listeners. Those listeners
will eventually get to those buffered messages when they finish
processing they're current message, get back to their loop, and find the
lower priority messages. So it could simply mean that lower priority
messages are ignored for longer than they otherwise would be.

Oh, and you'll probably want some logic so that if all three queues are
empty, you don't sit spinning.

Matthew




More information about the rabbitmq-discuss mailing list