개인 저장용 블로그

RabbitMQ Tutorials - Topics (7) 본문

오픈소스/RabbitMQ

RabbitMQ Tutorials - Topics (7)

우엉잇 2022. 4. 4. 13:27
이번 목차는 Topics 에 대한 내용입니다. 

 

이전 소단원에서는 diret exchange 이용하여 선택적으로 로그를 수신 있게 하였습니다. diret exchange 사용하여 시스템을 개선 되었지만 여전히 한계가 있습니다. 여러 기준에 따라 routing 수행 없습니다.

 

해당 소단원에서는 심각도와 기능을 기반으로 로그를 라우팅하는 unix svslog 처럼 사용하기 위해 topic 사용 예정입니다.

 

- Topic exchange

 

Topic exchange 전송된 메시지는 임의의 라우팅 키를 가질 없습니다. (.) 으로 구분된 단어 목록이어야 합니다. 단어는 무엇이든 있지만 일반적으로 메시지와 연결된 일부 기능을 지정합니다.

바인딩 키도 같은 형식이어야 합니다. Topic exchange 논리는 direct exchange 유사합니다. 특정 라우팅 키로 보낸 메시지는 일치하는 바인딩 키로 바인딩 모든 큐에 전달합니다. 그러나 바인딩 키에는 가지의 특별한 경우가 있습니다.

* : 단어만을 지정 가능
# : 단어 이상을 지정 가능

동작방식 (출처 : RabbitMQ 홈페이지)

위와 같이 어떤 토픽이냐에 따라 해당 토픽에 관심이 있는 Sonsumer에게 메시지를 선별젹으로 보내게 됩니다.


예를 들어, *.orange.* 경우 a.orange.b 형식으로 매칭되고, a.b.orange 매칭되지 않습니다. 또한 lazy.# 경우 lazy.aa.bb 혹읜 lazy.cc.dd 혹시 lazy.abcd.beee 모두와 매칭 됩니다.

1.2.5.1.  Python

 

- Python 소스 코드 작성


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()


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()

- Message Queue테스트

# 모든 메시지 허용

mwno@mwno-VirtualBox:/product/python$ python3 receive_log_topic.py "#"
 [*] Waiting for logs. To exit press CTRL+C
 
mwno@mwno-VirtualBox:/product/python$ python3 emit_log_topic.py "test" "test"
 [x] Sent 'test':'test'
 
mwno@mwno-VirtualBox:/product/python$ python3 receive_log_topic.py "#"
 [*] Waiting for logs. To exit press CTRL+C
 [x] 'test':b'test'

 

# 커널 로그 전부 받기

mwno@mwno-VirtualBox:/product/python$ python3 receive_log_topic.py "kern.*"
 [*] Waiting for logs. To exit press CTRL+C
mwno@mwno-VirtualBox:/product/python$ python3 emit_log_topic.py "kern.warn" "kernel warnning log"
 [x] Sent 'kern.warn':'kernel warnning log'
 
mwno@mwno-VirtualBox:/product/python$ python3 receive_log_topic.py "kern.*"
 [*] Waiting for logs. To exit press CTRL+C
 [x] 'kern.warn':b'kernel warnning log'

# critical 로그 받기

mwno@mwno-VirtualBox:/product/python$ python3 receive_log_topic.py "*.critical"
 [*] Waiting for logs. To exit press CTRL+C

 
mwno@mwno-VirtualBox:/product/python$ python3 emit_log_topic.py "kern.critical" "critical log"
 [x] Sent 'kern.critical':'critical log'
 
mwno@mwno-VirtualBox:/product/python$ python3 receive_log_topic.py "*.critical"
 [*] Waiting for logs. To exit press CTRL+C
 [x] 'kern.critical':b'critical log'

 

# 여러 바인딩 로그 받기

mwno@mwno-VirtualBox:/product/python$ python3 receive_log_topic.py "kern.*" "*.critical"
 [*] Waiting for logs. To exit press CTRL+C
 
----------------
mwno@mwno-VirtualBox:/product/python$ python3 emit_log_topic.py "kern.test" "first message"
 [x] Sent 'kern.test':'first message'
 
mwno@mwno-VirtualBox:/product/python$ python3 emit_log_topic.py "test.critical" "Second  message"
 [x] Sent 'test.critical':'Second  message'
 
mwno@mwno-VirtualBox:/product/python$ python3 emit_log_topic.py "kern.critical" "Third message"
 [x] Sent 'kern.critical':'Third message'
 
mwno@mwno-VirtualBox:/product/python$ python3 emit_log_topic.py "critical.kern" "no message"
 [x] Sent 'critical.kern':'no message'
 
----------------
mwno@mwno-VirtualBox:/product/python$ 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'