Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I pool channels in rabbitmq?

I have been trying to share connection between threads and have channels open only on thread creation but after researching a bit more, I think I want to also try to connection pooling. How can I do this on rabbitmq? or is this a general idea I can apply generally? My goal is to spawn X threads and then have them not have to open new channels(which requires round robin establishment between client and server).

Since the threads are their own class, I'm not sure if I need to put the pool in the class itself that spawns the threads or where they go?I also have multiple types of threads I would want to share these connections between(not just a single one). Is that possible?

Just to give you a general idea, here's how connections/channels are estblished in rabbitmq:

ConnectionFactory factory = new ConnectionFactory();
    factory.setHost("localhost");
    Connection connection = factory.newConnection();
    Channel channel = connection.createChannel();  //I want to share several of these between threads
like image 843
Lostsoul Avatar asked Apr 28 '12 17:04

Lostsoul


People also ask

How many channels can RabbitMQ handle?

You can use one Channel for everything. However, if you have multiple threads, it's suggested to use a different Channel for each thread. Channel thread-safety in Java Client API Guide: Channel instances are safe for use by multiple threads.

How do I check my channel on RabbitMQ?

Inspecting Channels and Their State Using CLI Toolsrabbitmqctl list_connections and rabbitmqctl list_channels are the primary commands for inspecting per-connection channel count and channel details such as the number of consumers, unacknowledged messages, prefetch and so on.

Should I reuse RabbitMQ channel?

Don't open and close connections or channels repeatedly. Even channels should be long-lived if possible, e.g., reuse the same channel per thread for publishing. Don't open a channel each time you are publishing.

How do I close a channel on RabbitMQ?

A connection can be closed via the RabbitMQ Management Interface. Enter the connection tab and press on the connection. Go to the bottom of the page and press Close this connection, followed by pressing Force Close.


2 Answers

All you need is a pool of Channel objects that your threads can pull from.

The Apache commons actually already has a generic ObjectPool you can use.

The javadoc for the interface can be found here: http://commons.apache.org/pool/api-1.6/org/apache/commons/pool/ObjectPool.html

The javadoc for one of their pre-built implementations can be found here: http://commons.apache.org/pool/api-1.6/org/apache/commons/pool/impl/GenericObjectPool.html

A tutorial for using it can be found here: http://commons.apache.org/pool/examples.html

If this is over-complicated for you simple needs, really all you need to do is write a class that manages a set of Channel objects, allowing threads to check them out and return them to the pool, with the appropriate synchronization to prevent two threads from getting ahold of the same Channel

like image 157
Brian Roach Avatar answered Sep 28 '22 06:09

Brian Roach


You can also use ThreadLocal object, in case you use the channels.

RabbitMQ advises you to use channels per thread, so that would be a perfect match.

Sample code:

private final ThreadLocal<Channel> channels = new ThreadLocal<>();
...
Channel channel = channels.get();
 if (channel == null){
        channel = connection.createChannel();
        channels.set(channel);
    }

no need to close the channels, as they will be closed by your application when the connection is closed.

However, this solution might not suit you well if you're heavily creating new threads since that will allocate a lot of new channels that will never be closed. But if you do something like that, you are probably doing something wrong.

like image 38
Roman Avatar answered Sep 28 '22 05:09

Roman