KS blog

killins.egloos.com

포토로그



RabbitMQ with Python #5/6 by KillinS

AMQP의 exchange type 중 사실 가장 유용한것은 topic이라고 할 수 있다. direct의 경우 routing_key에 의한 binding이 1:1 매칭이기 때문에 매번 바인딩을 따로 설정해줘야 하는 불편함이 있는 반면, topic은 1:n의 매칭을 가능하게 하므로 좀 더 유연한 binding rule을 사용할 수 있다. RabbitMQ는 AMQP를 따르므로 topic에서 word를 구분하는 기준은 "."이고, 사용하는 특수문자는 "*"과 "#" 두가지이다.
  • * : 1개의 word에 대응
  • # : 0개 이상의 word에 대응
Exchange type으로 topic을 사용할 때 바인딩하는 방법은 위의 특수문자를 이용한다는것 이외에는 direct와 동일하므로 바로 아래의 전체 소스를 살펴보면 이해가 될것이다.


    # emit_logs_topic.py : producer
    import pika
    import sys

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

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

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


    # receive_logs_topic.py : consumer
    import pika
    import sys

    def callback(ch, method, properties, body):
        print "[x] %r:%r" % (method.routing_key, body,)

    connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
    channel = connection.channel()
    channel.exchange_declare(exchange='logs_topic', type='topic')
    result = channel.queue_declare(exclusive=True)
    queue_name = result.method.queue

    binding_keys = sys.argv[1:]
    if not binding_keys:
        print >> sys.stderr, "Error : input binding_keys"
        sys.exit(1)

    for binding_key in binding_keys:
        channel.queue_bind(exchange='logs_topic', queue=queue_name, routing_key=binding_key)
    channel.basic_consume(callback, queue=queue_name, no_ack=True)

    print "[*] Waiting for logs. To exit press CTRL+C"
    channel.start_consuming()


consumer를 실행할 때 아래의 예와 같이 "*"나 "#"을 이용하여 word 단위로 topic에 의한 binding을 구성할 수 있다.


    python receive_logs_topic.py "#"

    python receive_logs_topic.py "korn.*"

    python receive_logs_topic.py "*.critical"


그리고 producer에서 메시지를 송신할 때도 "*"와 "#"을 이용하여 word 단위로 라우팅 키를 설정하여 송신하면 된다.

    python emit_logs_topic.py bourne BourneMsg

    python emit_logs_topic.py korn.info KornInfoMsg

    python emit_logs_topic.py korn.critical KornCriticalMsg

    python emit_logs_topic.py bourne.critical BourneCriticalMsg


* 출처 : RabbitMQ.com