Announcement Announcement Module
Collapse
No announcement yet.
Fanout Exchange Sample App Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Fanout Exchange Sample App

    Hi,

    I am trying to run a simple 'fanout' app. I am not able to find out that how does a listener configures the binding of its queue to an existing 'fanout' exchange. As I understand, there are two ways to listen to a message:

    =============
    1. Implement MessageListener and override the onMessage method along with the configuration of SimpleMessageListenerContainer (where there is no mention of exchange & only the queueName can be set).

    2. Use the RabbitTemplate's receiveAndConvert() method along with the configuration of RabbitTemplate (where there is no mention of queue & only the exchange can be set).

    ============

    So the question is where and how do we bind the exchange (on which a published message has been sent) to the consumer/listener's queue?

    Thanks,
    Kshitiz

  • #2
    In the AMQP model, Message reception is always via Queues. Only the producer should be concerned with Exchanges. This provides loose-coupling between the producer's Exchange and the consumer's Queue. Then, all connections between Exchange and Queues are configured as "bindings" on the broker itself. The specific rules for binding depend upon the Exchange type. For a Fanout Exchange, any Queue bound to that Exchange will receive any message sent to that Exchange.

    From the Spring AMQP perspective, if you are defining a MessageListener container, you would specify the Queue name that is bound to the FanoutExchange. When using the RabbitTemplate, you would specify the "queue" property on the template (with the value being the Queue's name) or you would pass the Queue's name at runtime to the receive/receiveAndConvert method.

    Hope that helps.
    -Mark

    Comment


    • #3
      Thanks Mark,

      But I still do not understand when you say

      "For a Fanout Exchange, any Queue bound to that Exchange will receive any message sent to that Exchange"

      or when you say

      "From the Spring AMQP perspective, if you are defining a MessageListener container, you would specify the Queue name that is bound to the FanoutExchange."

      My doubt is exactly that How do we bind a listener's Queue to a 'particular' "Fanout" exchange programmatically or through configurations.

      Comment


      • #4
        Bindings can be done at the broker level in which case you can read this:
        http://www.rabbitmq.com/admin-guide.html

        Or, you can use the Spring AMQP Binding API:
        http://static.springsource.org/sprin...single/#d0e134

        Comment


        • #5
          Thanks Mark,

          So we have to bind the exchange and queues at the broker level. does that mean we should know in advance that how many consumers are sitting out there and on which queue(s) are they listening?

          Kshitiz

          Comment


          • #6
            Well, each Consumer will be registered with a Queue, but keep in mind that a Queue is not itself "fanning out" Messages. In other words, even if 3 consumers register with the same Queue, only 1 will get each Message EVEN IF the Queue is bound to a FanoutExchange. On the other hand, there might be 100 other Queues bound to the FanoutExchange and each Queue will receive every Message sent to that Exchange.

            What that means is that it's quite common to create anonymous, exclusive, non-durable Queues for a specific consumer. The Queue can be bound to the FanoutExchange and receive all messages. It's cheap to do this at runtime.

            Does that make sense?
            -Mark

            Comment


            • #7
              Hi Mark,

              Please forgive me If I am not understanding it. I have to publish a message and that should be delivered to each subscriber for that message. Now, what are the steps I should take after creating an exchange and send a message to that exchange..

              1. Should I keep some queues (bounded to that exchange) handy so that a consumer binds to one of those handy queues and get the message?
              In this case, I should be knowing how many consumers are going to get that message and make those many queues handy at the broker level..
              Seems not correct as I can not know in advance that how many consumers will be consuming that message.

              OR

              2. Create a queue, and bind to that queue in the consumer's code
              but I don't know how to do that as I understand, there are two ways to listen to a message:
              Either implement MessageListener and override the onMessage method along with the configuration of SimpleMessageListenerContainer (where there is no mention of exchange & only the queueName can be set).
              Or use the RabbitTemplate's receiveAndConvert() method along with the configuration of RabbitTemplate (where there is no mention of queue & only the exchange can be set).

              Please let me know about the other ways I should do it..

              Thanks,
              Kshitiz

              Comment


              • #8
                Okay Mark,

                I guess I understand it now, but now I am stuck at another point. Messages are published correctly at the queue which exists exclusively for a particular consumer (that means I have to make as many queues as there are consumers if I want that the message published should be available to each consumer) , and those messages are shown when I fire rabbitmqctl.bat list_queues, but they are not being consumed at the consumer end.

                My application is a war file deployed in Tomcat and there is no exception as such.

                I have implemented MessageListener and overriden the onMessage method along with the configuration of SimpleMessageListenerContainer.

                Do I need to acknowledge the message or something else to consume it properly?

                Comment


                • #9
                  Here are my consumer configurations:

                  <!-- configure a message consumer thread -->
                  <bean id="messageConsumer" class="com.xyz.MessageConsumer" />
                  <!-- pass the above messageListener object and other settings to SimpleMessageListenerContainer in Rabbit API-->
                  <bean class="org.springframework.amqp.rabbit.listener.Si mpleMessageListenerContainer" p:connectionFactory-ref="connectionFactory" p:queueName="sampleQueue" p:messageListener-ref="messageConsumer" />

                  and here is MessageConsumer.java

                  public class MessageConsumer implements MessageListener {
                  @Override
                  public void onMessage(Message message) {
                  System.out.println("Received message: " + message);
                  }
                  }

                  Comment


                  • #10
                    That should be working if you are connected to the same broker instance and see messages being sent to 'sampleQueue' when running rabbitmqctl list_queues. I assume you are adding the 'messages' arg when running that command, and you see the number you expect there?

                    Comment


                    • #11
                      Interestingly the same kind of problem I had faced when using ActiveMQ with Spring JMS Template. I had to add this property in spring's jms:listener-container property to make that work.

                      acknowledge="auto"

                      Now when using RabbitMQ with Spring AMQP, I suppose I will have to use a similar property but not able to find out what that is...

                      Comment


                      • #12
                        With JMS, "auto" is the default, so setting it explicitly should not have any effect. Are you sure that was what fixed your problem?

                        Likewise in the Spring AMQP code, even though things are a bit different, the default configuration should not be getting in your way here. Have you compared your configuration with that in our 'helloworld' sample?

                        Comment


                        • #13
                          I will be putting up the configurations on the forum which worked for me pretty soon.

                          Thanks a lot Mark!

                          Comment

                          Working...
                          X