본문 바로가기
오픈소스/RabbitMQ

[RMQ] Python으로 배우는 RabbitMQ 튜토리얼(5) - Topic

by sangyeon 2022. 1. 20.
728x90

1. Topic이란

RabbitMQ에서 토픽이란 routing_key 전체가 일치하거나 일부 패턴과 일치하는 모든 Queue에 메세지를 전달하는 역할을 한다. 

이미지 출처 - https://www.rabbitmq.com/tutorials/tutorial-five-python.html

위와 같이 어떤 토픽이냐에 따라 해당 토픽에 관심이 있는 Consumer에게 메세지를 선별적으로 보내게 된다.

이때 토픽에서 와일드 카드 기능을 제공하게 되는데,

 

1. *(star) : 한 단어만을 지정 가능

2.  #(hash) : 한 단어 이상을 지정 가능

 

예를 들어,

*.orange.* 의 경우 a.orange.b 형식으로 매칭되고, a.b.orange의 경우에는 매칭되지 않는다.

또한 lazy.#의 경우, lazy.aa.bb 혹은 lazy.cc.dd 혹은 lazy.abcd.efghi 모두와 매칭 된다.

 

토픽의 장점은 임의의 라우팅 키를 가질 수 있다는 것이다.

 

 

2. 소스 코드(예제)

 

- receive_log_topic.py

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

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

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

result = channel.queue_declare('', exclusive=True)
queue_name = result.method.queue

binding_keys = sys.argv[1:]
if not binding_keys:
    sys.stderr.write("Usage: %s [binding_key]...\n" % sys.argv[0])
    sys.exit(1)

for binding_key in binding_keys:
    channel.queue_bind(
        exchange='topic_logs', queue=queue_name, routing_key=binding_key)

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


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


channel.basic_consume(
    queue=queue_name, on_message_callback=callback, auto_ack=True)

channel.start_consuming()

수신할 routing_key를 변수 처리한다. topic의 경우 와일드카드를 사용해 특정 형식의 routing_key를 만들 수 있다.

 

- emit_log_topic.py

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

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

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

routing_key = sys.argv[1] if len(sys.argv) > 2 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()

 

 

3. 소스 테스트

 

3-1. 어떤 메세지든 다 받는 receive 설정

root@master:~/RabbitMQ/ex5-topic# clear
root@master:~/RabbitMQ/ex5-topic# python3 emit_log_topic.py "test" "test"
 [x] Sent 'test':'test'

----------------------------------------------------------------------------------------------------------
root@master:~/RabbitMQ/ex5-topic# python3 receive_log_topic.py "#"
 [*] Waiting for logs. To exit press CTRL+C
 [x] 'test':b'test'

 

3-2. 커널 로그 전부를 받는 설정

root@master:~/RabbitMQ/ex5-topic# python3 emit_log_topic.py "kern.warn" "kernel warnning log"
 [x] Sent 'kern.warn':'kernel warnning log'

----------------------------------------------------------------------------------------------------------
root@master:~/RabbitMQ/ex5-topic# clear
root@master:~/RabbitMQ/ex5-topic# python3 receive_log_topic.py "kern.*"
 [*] Waiting for logs. To exit press CTRL+C
 [x] 'kern.warn':b'kernel warnning log'

 

3-3. Critical 로그에 대해서만 받는 설정

root@master:~/RabbitMQ/ex5-topic# python3 emit_log_topic.py "kern.critical" "critical log"
 [x] Sent 'kern.critical':'critical log'

----------------------------------------------------------------------------------------------------------
root@master:~/RabbitMQ/ex5-topic# python3 receive_log_topic.py "*.critical"
 [*] Waiting for logs. To exit press CTRL+C
 [x] 'kern.critical':b'critical log'

 

3-4. 여러 바인딩 생성

root@master:~/RabbitMQ/ex5-topic# python3 emit_log_topic.py "kern.test" "first message"
 [x] Sent 'kern.test':'first message'
root@master:~/RabbitMQ/ex5-topic# python3 emit_log_topic.py "test.critical" "Second  message"
 [x] Sent 'test.critical':'Second  message'
root@master:~/RabbitMQ/ex5-topic# python3 emit_log_topic.py "kern.critical" "Third message"
 [x] Sent 'kern.critical':'Third message'
root@master:~/RabbitMQ/ex5-topic# python3 emit_log_topic.py "critical.kern" "no message"
 [x] Sent 'critical.kern':'no message'


----------------------------------------------------------------------------------------------------------
root@master:~/RabbitMQ/ex5-topic# python3 receive_log_topic.py "kern.*" "*.critical"
 [*] Waiting for logs. To exit press CTRL+C
 [x] 'kern.test':b'first message'
 [x] 'test.critical':b'Second  message'
 [x] 'kern.critical':b'Third message'
728x90