RabbitMQ 파이썬 튜토리얼 05 - Topic


튜토리얼 리스트

전제조건

이 튜토리얼에서는 RabbitMQ가 표준 포트(5672)의 localhost에 설치되어 실행되고 있다고 가정합니다. 다른 호스트, 포트 또는 자격 증명을 사용하는 경우 연결 설정을 변경해야 합니다.

이 포스트에서는

이전 튜토리얼에서는 로깅 시스템을 개선했습니다. 더미 브로드캐스드만 가능한 fanout exchange을 사용하는 대신, 우리는 direct 발행을 사용하여 선택적으로 로그를 수신 할 수있었습니다. direct exchange을 사용하여 시스템이 개선되었지만 여전히 여러 가지 기준에 따라 라우팅을 수행 할 수는 없습니다.

로깅 시스템에서는 심각도를 기반으로 로그뿐만 아니라 로그를 생성 한 소스를 기반으로 로그를 구독하고자 할 수 있습니다. 심각도 (info / warn / crit …)와 facility (auth / cron / kern …)를 기반으로 로그를 라우팅하는 syslog unix 도구에서 이 개념을 알 수 있습니다.

그것은 우리에게 많은 유연성을 줄 것입니다. 우리는 ‘cron’에서 오는 중요한 오류뿐만 아니라 ‘kern’의 모든 로그도 들을 수 있습니다.

로깅 시스템에서 이를 구현하려면 보다 복잡한 topic exchange에 대해 알아야합니다.

Topic exchange

topic exchange에 전송된 메시지에는 임의의 routing_key가 있을 수 없습니다. 점으로 구분 된 단어 목록이어야 합니다. 단어는 무엇이든 가능하지만 일반적으로 메시지에 연결된 일부 기능을 지정합니다. 몇 가지 유효한 라우팅 키 예 : “stock.usd.nyse”, “nyse.vmw”, “quick.orange.rabbit”. 라우팅 키에는 최대 255 바이트의 길이로 원하는 단어로 구성할 수 있습니다.

바인딩 키는 동일한 양식이어야 합니다. topic exchange의 논리는 direct 라우팅과 유사합니다. 특정 라우팅 키와 함께 전송 된 메시지는 일치하는 바인딩 키로 바인드 된 모든 큐에 전달됩니다. 그러나 바인딩 키에는 중요한 두 가지 중요한 경우가 있습니다.

  • * (별표)는 정확히 한 단어를 대신 할 수 있습니다.
  • # (해시)는 0 개 이상의 단어를 대체 할 수 있습니다.

예를 들어 설명하는 것이 가장 쉽습니다.

직접 교환기

이 예에서는 모든 동물을 묘사하는 메시지를 보냅니다. 메시지는 세 단어 (두 개의 점)로 구성된 라우팅 키와 함께 전송됩니다. “<celerity>.<color>.<species>” 라우팅 키의 첫 번째 단어는 속성, 두 번째 및 세 번째 을 나타냅니다.

우리는 세 가지 바인딩을 만들었습니다. Q1은 바인딩 키 “*.orange.*“로 바인딩되고 Q2는 “*.*.rabbit”및 “lazy.#“로 바인딩됩니다.

이러한 바인딩은 다음과 같이 요약 할 수 있습니다.

  • Q1은 모든 ‘orange’ 색 동물에 관심이 있습니다.
  • Q2는 토끼에 관한 모든 것과 lazy 동물에 관한 모든 것을 듣기를 원합니다.

라우팅 키가 “quick.orange.rabbit”로 설정된 메시지가 두 큐에 전달됩니다. “lazy.orange.elephant” 메시지도 양쪽 모두에 전달됩니다. 반면에 “quick.orange.fox”는 첫 번째 큐로 이동하고 “lazy.brown.fox”는 두 번째 큐로 이동합니다. “lazy.pink.rabbit”은 두 번째 큐 두 개의 바인딩과 모두 일치하더라도 두 번째 큐에 두번이 아닌 한번만 전달됩니다. “quick.brown.fox”는 바인딩과 일치하지 않으므로 버려집니다.

우리가 규칙을 생각하지 않고 “orange” 또는 “quick.orange.male.rabbit”와 같은 한두 단어로 메시지를 보내면 어떻게 될까요? 이 메시지들은 어떤 바인딩과도 일치하지 않을 것이고 잃어 버리게 될 것입니다. 반면에 “lazy.orange.male.rabbit”은 네 단어가 있더라도 마지막 바인딩과 일치하고 두 번째 큐로 전달됩니다.

Topic exchange

topic exchange은 강력하고 다른 exchange 처럼 작동 할 수 있습니다. 큐가 “#”(해시) 바인딩 키로 바인딩되면 - fanout exchange 에서처럼 라우팅 키에 관계없이 모든 메시지를 수신합니다. 특수 문자 “*“(별표)와 “#“(해시)이 바인딩에 사용되지 않으면 topic exchange은 direct exchange 처럼 작동합니다.

최종 코드

우리는 로깅 시스템에서 topic exchange을 사용할 것입니다. 로그의 라우팅 키에는 “<facility>. <severity>“라는 두 단어가 있다는 가정하에 시작하겠습니다.코드는 이전 자습서와 거의 같습니다.

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

receive_logs_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(callback,
                      queue=queue_name,
                      no_ack=True)

channel.start_consuming()

실행되는 모든 로그를 수신하려면 다음을 실행하십시오.

python receive_logs_topic.py "#"

“kern”시설에서 모든 로그를 받으려면 다음을 실행하십시오.

python receive_logs_topic.py "kern.*"

또는 “중요”로그에 대해서만 듣고 싶다면 :

python receive_logs_topic.py "*.critical"

여러 개의 바인딩을 만들 수 있습니다.

python receive_logs_topic.py "kern.*" "*.critical"

라우팅 키 “kern.critical”을 사용하여 로그를 출력하려면 다음을 입력하십시오.

python emit_log_topic.py "kern.critical" "A critical kernel error"

이 코드는 라우팅 또는 바인딩 키에 대해 어떠한 가정도하지 않으므로 두 개 이상의 라우팅 키 매개 변수로 재생할 수 있습니다.

튜토리얼 리스트