Is there a performance difference between pooling connections or channels in rabbitmq?

QueueMessage QueueRabbitmqTask Queue

Queue Problem Overview


I'm a newbie with Rabbitmq(and programming) so sorry in advance if this is obvious. I am creating a pool to share between threads that are working on a queue but I'm not sure if I should use connections or channels in the pool.

I know I need channels to do the actual work but is there a performance benefit of having one channel per connection(in terms of more throughput from the queue)? or am I better off just using a single connection per application and pool many channels?

note: because I'm pooling the resources the initial cost is not a factor, as I know connections are more expensive than channels. I'm more interested in throughput.

Queue Solutions


Solution 1 - Queue

I have found this on the rabbitmq website it is near the bottom so I have quoted the relevant part below.

The tl;dr version is that you should have 1 connection per application and 1 channel per thread. Hope that helps.

> Connections > > AMQP connections are typically long-lived. AMQP is an application > level protocol that uses TCP for reliable delivery. AMQP connections > use authentication and can be protected using TLS (SSL). When an > application no longer needs to be connected to an AMQP broker, it > should gracefully close the AMQP connection instead of abruptly > closing the underlying TCP connection. > > Channels > > Some applications need multiple connections to an AMQP broker. > However, it is undesirable to keep many TCP connections open at the > same time because doing so consumes system resources and makes it more > difficult to configure firewalls. AMQP 0-9-1 connections are > multiplexed with channels that can be thought of as "lightweight > connections that share a single TCP connection". > > For applications that use multiple threads/processes for processing, > it is very common to open a new channel per thread/process and not > share channels between them. > > Communication on a particular channel is completely separate from > communication on another channel, therefore every AMQP method also > carries a channel number that clients use to figure out which channel > the method is for (and thus, which event handler needs to be invoked, > for example).

It is advised that there is 1 channel per thread, even though they are thread safe, so you could have multiple threads sending through one channel. In terms of your application I would suggest that you stick with 1 channel per thread though.

Additionally it is advised to only have 1 consumer per channel.

These are only guidelines so you will have to do some testing to see what works best for you.

This thread has some insights here and here.

Despite all these guidelines this post suggests that it will most likely not affect performance by having multiple connections. Though it is not specific whether it is talking about client side or server(rabbitmq) side. With the one point that it will of course use more systems resources with more connections. If this is not a problem and you wish to have more throughput it may indeed be better to have multiple connections as this post suggests multiple connections will allow you more throughput. The reason seems to be that even if there are multiple channels only one message goes through the connection at one time. Therefore a large message will block the whole connection or many unimportant messages on one channel may block an important message on the same connection but a different channel. Again resources are an issue. If you are using up all the bandwidth with one connection then adding an additional connection will have no increase performance over having two channels on the one connection. Also each connection will use more memory, cpu and filehandles, but that may well not be a concern though might be an issue when scaling.

Solution 2 - Queue

In addition to the accepted answer:

If you have a cluster of RabbitMQ nodes with either a load-balancer in front, or a short-lived DNS (making it possible to connect to a different rabbit node each time), then a single, long-lived connection would mean that one application node works exclusively with a single RabbitMQ node. This may lead to one RabbitMQ node being more heavily utilized than the others.

The other concern mentioned above is that the publishing and consuming are blocking operations, which leads to queueing messages. Having more connections will ensure that 1. processing time for each messages doesn't block other messages 2. big messages aren't blocking other messages.

That's why it's worth considering having a small connection pool (having in mind the resource concerns raised above)

Solution 3 - Queue

The "one channel per thread" might be a safe assumption (I say might as I have not made any research by myself and I have no reason to doubt the documentation :) ) but beware that there is a case where this breaks:

If you you use RPC with RabbitMQ Direct reply-to then you cannot reuse the same channel to consume for another RPC request. I asked for details about that in the google user group and the answer I got from Michael Klishin (who seems to be actively involved in RabbitMQ development) was that

> Direct Reply to is not meant to be used with channel sharing either way.

I've email Pivotal to update their documentation to explain how amq.rabbitmq.reply-to is working under the hood and I'm still waiting for an answer (or an update).

So if you want to stick to "one channel per thread" beware as this will not work good with Direct reply-to.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionLostsoulView Question on Stackoverflow
Solution 1 - QueuerobthewolfView Answer on Stackoverflow
Solution 2 - QueueBozhoView Answer on Stackoverflow
Solution 3 - QueueStelios AdamantidisView Answer on Stackoverflow