Search code examples
pythonrabbitmqpika

pika rabbitmq topic producer. do I have to bind a routing key(s) to the queue?


I understand the need for a topic consumer to bind all of the routing keys it's interest in receiving, but I'm a bit confused as to why the topic producer in the following example

https://github.com/pika/pika/blob/master/docs/examples/asynchronous_publisher_example.rst

def on_queue_declareok(self, method_frame):
        """Method invoked by pika when the Queue.Declare RPC call made in
        setup_queue has completed. In this method we will bind the queue
        and exchange together with the routing key by issuing the Queue.Bind
        RPC command. When this command is complete, the on_bindok method will
        be invoked by pika.

        :param pika.frame.Method method_frame: The Queue.DeclareOk frame

        """
        LOGGER.info('Binding %s to %s with %s',
                    self.EXCHANGE, self.QUEUE, self.ROUTING_KEY)
        self._channel.queue_bind(self.on_bindok, self.QUEUE,
                                 self.EXCHANGE, self.ROUTING_KEY)

in on_queue_declareok() binds the queue to a routing key since the producer isn't listening for any topics. Am I supposed to bind all of the routing keys which the producer will send out?

I know that the following example

http://www.rabbitmq.com/tutorials/tutorial-five-python.html

is using a blocking connection as compared to the SelectConnection which I'm using, but it's producer doesn't bind any routing keys to the queue - it simply does basic_publish() for an arbitrary routing key.

#!/usr/bin/env python
import pika
import sys

connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = connection.channel()

channel.exchange_declare(exchange='topic_logs', type='topic')

routing_key = sys.argv[1] if len(sys.argv) > 1 else 'anonymous.info'
message = ' '.join(sys.argv[2:]) or 'Hello World!'
channel.basic_publish(exchange='topic_logs', routing_key=routing_key, body=message)
print " [x] Sent %r:%r" % (routing_key, message)
connection.close()

Any clarification would be appreciated.

-Scott


Solution

  • I think you a bit confused between producers and consumers. Producer publishes messages to the exchange. not to the queue. And Consumer reads from the queue, not from exchange.

    The question is who is binding queue to the exchange is application specific. It can be different from one application to another. In some cases you want you producer to know where this message will end up. In other cases it doesn't matter, and consumer can specify what messages it is interested in.

    If you don't know you requirements yet, you can "simply" (not the best approach) create a queue in the UI and bind it to what ever exchange you want. Then in your producer you will hardcode the exchange and routing key, and in consumer you will hardcode the queue name.

    A binding is a relationship between an exchange and a queue. This can be simply read as: the queue is interested in messages from this exchange.

    Bindings can take an extra routing_key parameter. To avoid the confusion with a basic_publish parameter we're going to call it a binding key. This is how we could create a binding with a key: