[rabbitmq-discuss] ShutdownSignalException second 'channel.open'

Yogesh Ketkar yogimogi at gmail.com
Tue Jan 31 13:56:55 GMT 2012


I am using RabbitMQ server version 2.7.1.
Java Client Jar used is
rabbitmq-java-client-bin-2.7.1/rabbitmq-client.jar

> The Shutdown seems to be being called because the channel is being opened twice.
> The broker complains about this and closes the connection. Are you creating
> channels on different threads simultaneously?
Yes indeed, I am creating channels on different threads.

> I don't think the basicPublish will fail if the queue doesn't exist. Why would
> you create a new channel in this case?
Yes, you are right. I will basically lose the message in this case.

Now about overall problem statement.
My application has a main queue which looks like
MainQueue
  - App1-Event1
  - App2-Event1
  - App1-Event2
  - App1-Event3
  - App3-Event1
  - App3-Event2
  - App2-Event2

Basically there are going to be events from different Apps (there can
be thousands of apps) and events belonging to an App must
be processed sequentially. Events across different apps can and should
be be processed in parallel.
So I have only one consumer on MainQueue (using basicConsume) which
reads events from MainQueue and just moves it to appropriate declared/
redeclared queue.
So this is how new queue structure would look like.

App1
  - App1-Event1
  - App1-Event2
  - App1-Event3

App2
  - App2-Event1
  - App2-Event2

App3
  - App3-Event1
  - App3-Event2


Now again when Event1 is processed from Queue App1, Event2 of App1
can't be processed unless processing of Event1 is complete.
Processing of event involves asynchronous communication with external
systems, so once Event1 is fetched (and acknowledged) from queue
App1,
I create another queue like
App1_Return
  - App1-Event1-TaskId

I need to query external system using TaskId after certain time
interval, to check status of event processing of Event1. Once I get
the status (either sucess or failure)
I discard App1-Event1-TaskId and ready to process App1-Event2. So all
_Return queues will only have one event at any point of time.

An event on an app might even occur once a day. So I don't want to
keep so many queues (potentially 20000 if there are 10000 apps)
hanging around.
Both auto_delete and x-expires are not very useful as in both the
schemes, queues get deleted even when they have messages.
Ideally whenever last message from any Queue (except MainQueue) is
consumed, I want to delete that queue. Of course, one has to make sure
while a queue is getting deleted, there might be an event destined for
that. So if one guy is doing
queueDelete('somequeue', true, true) and other guy is doing
queueDeclare, queueBind, basicPublish. If queueDelete gets executed
after
queueBind, message will be lost.

One of the reasons, I don't do basicConsume on queues is, I am going
to have thousands of queues. I rather thought it would be easier to
have a thread pool, each consuming just one message from a queue in
round-robin fashion.

As was mentioned in some other response, I will certainly not create a
new channel in every thread, but would rather try and reuse them.


Thanks for all the help.
Regards, Yogesh



On Jan 31, 5:19 pm, Steve Powell <st... at rabbitmq.com> wrote:
> Yogesh,
>
> Please can you provide some information about your environment? And your
> application? What version of RabbitMQ (and client) are you using?
>
> In your stack trace the ShutdownListener you registered is apparently being
> called, because the Connection is being shut down. It is not clear why this
> exception (and its associated stack trace) appears, it seems to come from your
> Listener code, but perhaps that does nothing.
>
> The Shutdown seems to be being called because the channel is being opened twice.
> The broker complains about this and closes the connection. Are you creating
> channels on different threads simultaneously? (Looking at your app 'design' you
> might be.) Depending upon the version of RabbitMQ this might cause a problem.
>
> I'm afraid your application design is unclear:
>
> > This is how I handle doing basicPublish and basicGet on potentially
> > non-existent queues
> > - publish involves 3 steps
> >  queueDeclare
> >  queueBind
> >  basicPublish
> >  If some other thread deletes the queue after either queueDeclare or
> > queueBind, basicPublish fails and I again create a new
> >  channel and do these operations
>
> I don't think the basicPublish will fail if the queue doesn't exist. Why would
> you create a new channel in this case?
>
> Please explain why you expect the queue might be deleted by some other thread.
>
> > - if basicGet fails, I simply ignore it
>
> What do you mean by ignoring it? Do you poll the queue periodically? Why aren't
> you using basicConsume and a Consumer to get messages (which will be notified if
> the queue is deleted)?
>
> Steve Powell  (a loopy bunny)
> ----------some more definitions from the SPD----------
> vermin (v.) Treating the dachshund for roundworm.
> chinchilla (n.) Cooling device for the lower jaw.
> socialcast (n.) Someone to whom everyone is speaking but nobody likes.
>
> On 30 Jan 2012, at 04:33, Yogesh Ketkar wrote:
>
>
>
>
>
>
>
>
>
> > Only operations I ever do with com.rabbitmq.client.Connection in the
> > code are
> >    c.addShutdownListener
> >    c.createChannel
>
> > What does this error signify?
>
> > 2012-01-30 09:44:45,158 ERROR  [ConnectionShutdownHandler]
> > ShutdownListener
> > com.rabbitmq.client.ShutdownSignalException: connection error; reason:
> > {#method<connection.close>(reply-code=503, reply-text=COMMAND_INVALID
> > - second 'channel.open' seen, class-id=20, method-id=10), null,
> > "[B at 105691e"}
> >    at com.rabbitmq.client.impl.AMQConnection.shutdown(AMQConnection.java:
> > 641)
> >    at
> > com.rabbitmq.client.impl.AMQConnection.handleConnectionClose(AMQConnection. java:
> > 599)
> >    at
> > com.rabbitmq.client.impl.AMQConnection.processControlCommand(AMQConnection. java:
> > 571)
> >    at com.rabbitmq.client.impl.AMQConnection
> > $1.processAsync(AMQConnection.java:88)
> >    at
> > com.rabbitmq.client.impl.AMQChannel.handleCompleteInboundCommand(AMQChannel .java:
> > 144)
> >    at com.rabbitmq.client.impl.AMQChannel.handleFrame(AMQChannel.java:
> > 91)
> >    at com.rabbitmq.client.impl.AMQConnection
> > $MainLoop.run(AMQConnection.java:500)
>
> > Some additional info.
> > I create and close thousands of channels in the code. But at any point
> > of time there are not more than 20/21 channels open.
> > This is how I handle doing basicPublish and basicGet on potentially
> > non-existent queues
> > - publish involves 3 steps
> >  queueDeclare
> >  queueBind
> >  basicPublish
> >  If some other thread deletes the queue after either queueDeclare or
> > queueBind, basicPublish fails and I again create a new
> >  channel and do these operations
> > - if basicGet fails, I simply ignore it
>
> > regards, Yogesh
> > _______________________________________________
> > rabbitmq-discuss mailing list
> > rabbitmq-disc... at lists.rabbitmq.com
> >https://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss
>
> _______________________________________________
> rabbitmq-discuss mailing list
> rabbitmq-disc... at lists.rabbitmq.comhttps://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss


More information about the rabbitmq-discuss mailing list