[rabbitmq-discuss] Connection and channel resource management in servlet
Bertrand Guay-Paquet
bernie at step.polymtl.ca
Thu Mar 27 19:59:58 GMT 2014
Thank you very much for your reply Michael.
> 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.
I added this bit to my connection factory:
ConnectionFactory factory = newConnectionFactory();
factory.setRequestedHeartbeat(60);
theConnection = factory.newConnection();
>> 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.
I expect the message publishing activity to be low enough in the first
implementation that I'll create a global synchronized publisher for the
web app. I could always add more channels later if it becomes a bottleneck.
>
>> 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
> queue.
>
> See tutorial 2:
> http://www.rabbitmq.com/tutorials/tutorial-two-java.html
>
>> 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.
Thanks for the insight. I'll dig into this more. I was using manual acks
and extending DefaultConsumer so I must have gotten something else wrong.
Regards,
Bertrand
More information about the rabbitmq-discuss
mailing list