[rabbitmq-discuss] Connection and channel resource management in servlet

Michael Klishin mklishin at gopivotal.com
Wed Mar 26 18:24:13 GMT 2014

On 26 March 2014 at 20:44:04, Bertrand Guay-Paquet (bernie at step.polymtl.ca) wrote:
> > My current understanding and questions:
> 1) I don't see a need to have more than 1 Connection instance in  
> either
> the servlet or the client. This connection should be created  
> on
> application or servlet startup and closed on shutdown. Are there  
> pitfalls with long-lived connections or is this all handled  
> by RabbitMQ
> (keep-alive)?

RabbitMQ connections are supposed to be long-lived. Set heartbeat interval
to a lower value (say, 60 seconds) if you have a firewall between clients
and RabbitMQ.

> 2) How should I handle broken Connections to the broker? If a new  
> one
> must be created, do all the channels need to be reopened as well?

If a connection fails, it needs to be reopened, as do all the channels
on it. Some clients support automatic recovery from TCP connection
failures. Java client will offer this feature in the upcoming 3.3.0 release.
> 3) It seems like it would be bad practice to create a new channel  
> each
> time a web request wants to publish a message. Should I pool them?  
> Share
> a single one? Use ThreadLocals? Is there a problem if they're  
> never
> closed (the connection would be on shutdown though)? The java  
> client api
> documentation states that channels *should* be closed but that  
> it's not
> necessary.

Opening a channel is a network round trip. So is closing a channel. If that’s acceptable to you,
opening and closing a channel per request is fine. Channels should not be shared
across threads.

For Web apps, a single connection and channel is usually sufficient, although
in Java and .NET you need to understand how your framework dispatches requests
in order to avoid concurrent publishes on a shared channel. Thread locals
should work OK, especially if you can pre-initialise all channels. 

> 4) My tests seem to show that when a subscribed consumer throws  
> an
> exception in handleDelivery(), it consumes the rest of its buffered  
> messages and is then terminated.

That’s not correct. You likely use automatic acknowledgements and/or a
QueueingConsumer which accumulates all deliveries locally in a java.util.concurrent

See tutorial 2:

> Does that mean I should never  
> throw
> from handleDelivery()? Or should I monitor currently active  
> consumers
> and restart the failed ones?

Unhandled exceptions will be delegated to ExceptionHandler which
is configured per channel. If you use manual acknowledgements,
throwing exceptions in handleDelivery without acking or rejecting
a delivery is not a very good idea: RabbitMQ will think that the
delivery is still being processed, and will keep the message around.

Software Engineer, Pivotal/RabbitMQ

More information about the rabbitmq-discuss mailing list