RabbitMQ 파이썬 튜토리얼 01 - Hello World


튜토리얼 리스트

전제조건

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

소개

RabbitMQ는 메시지 브로커입니다. 메시지를 수락하고 전달합니다. 우체국을 생각해보죠. 우리는 보내려는 메일을 우체통에 넣으면 집배원이 메일을 받는 사람에게 배달해 줄거라고 믿습니다. RabbitMQ는 이러한 우체국의 역할을 합니다. RabbitMQ와 우체국의 가장 큰 차이점은 종이를 다루지 않는다는 것입니다. 대신 데이터 바이너리 메시지를 받아 저장하고 전달합니다. RabbitMQ와 일반적으로 메시징은 전문 용어를 사용합니다.

Producing 은 보낸다는 것 이외의 의미가 없습니다. 메시지를 보내는 프로그램을 프로듀서(producer)라고 합니다:

프로듀서

큐(queue)는 RabbitMQ 내부에 있는 우체통(메시지 임시 저장소)의 이름입니다. 메시지는 RabbitMQ 및 응용 프로그램을 통해 전달되고 큐에서만 저장합니다. 큐는 호스트의 메모리 및 디스크 제한에 의해서만 제한되며, 본질적으로 큐는 큰 메시지 버퍼입니다. 많은 프로듀서가 하나의 큐로 이동하는 메시지를 보낼 수 있으며 많은 컨슈머가 하나의 큐에서 데이터를 수신하려고 시도 할 수 있습니다. 큐를 나타내는 방법은 다음과 같습니다.

큐

Consuming 은 받는다는 의미와 비슷합니다. 컨슈머(Consumer)는 메시지를 받기 위해 기다리고 처리하는 프로그램입니다.

프로듀서

프로듀서, 컨슈머, 그리고 RabbitMQ는 같은 호스트에서 실행될 필요가 없고 실제로 대부분의 프로그램도 그렇습니다.

Hello World!

(Pika Python client 사용)

이 튜토리얼의 이번 부분에서는 두 개의 작은 프로그램을 파이썬으로 작성합니다. 단일 메시지를 보내는 프로듀서 (보내는 프로그램) 및 메시지를 받고 이를 출력하는 컨슈머 (받는 프로그램)입니다. 주고 받는 메시지는 “Hello World” 입니다. 아래 다이어그램에서 “P”는 프로듀서이고 “C”는 컨슈머입니다. 중간에 있는 상자는 큐입니다. RabbitMQ가 컨슈머를 대신하여 보관하는 메시지 버퍼입니다. 우리의 전반적인 디자인은 다음과 같습니다 :

프로듀서

프로듀서가 메시지를 “hello” 큐로 보냅니다. 컨슈머는 큐에서 메시지를 받습니다.

보내기 - Sending

프로듀서

우리의 첫 번째 프로그램 send.py는 하나의 메시지를 큐에 보냅니다. 우리가 해야 할 첫 번째 일은 RabbitMQ 서버와의 연결을 설정하는 것입니다.

#!/usr/bin/env python
import pika

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

이제 로컬 컴퓨터의 브로커 (localhost)와 연결됩니다. 다른 머신의 브로커에 연결하고 싶다면 여기에 이름이나 IP 주소를 지정하기만 하면 됩니다. 다음으로, 보내기 전에 수신자 큐가 있는지 확인해야 합니다. 존재하지 않는 위치로 메시지를 보내면 RabbitMQ는 메시지를 삭제합니다. 메시지가 배달 될 큐의 이름을 hello 를 만듭니다.

channel.queue_declare(queue='hello')

이 시점에서 우리는 메시지를 보낼 준비가 되었습니다. 첫 번째 메시지에는 Hello World 라는 문자열만 포함됩니다. 그것을 우리의 hello 큐로 보내고 싶습니다. RabbitMQ에서는 메시지를 큐로 직접 보낼 수 없으며 항상 exchange을 거쳐야 합니다. exchange에 대한 세부 사항에 신경쓰지 마세요. 추후에 exchange를 다루겠습니다. 지금 우리가 알아야 할 것은 빈 문자열로 식별되는 기본 exchange를 사용하는 방법 뿐입니다. 이 exchange은 특별합니다. 메시지를 보낼 큐를 정확히 지정할 수 있습니다. 큐 이름은 routing_key 매개 변수에 지정해야합니다.

channel.basic_publish(exchange='',
                      routing_key='hello',
                      body='Hello World!')
print(" [x] Sent 'Hello World!'")

프로그램을 종료하기 전에 네트워크 버퍼가 삭제 되었는지 확인하고 메시지가 실제로 RabbitMQ에 전달 되었는 지 확인해야 합니다. 우리는 연결을 닫으면서 확인할 수 있습니다.

connection.close()

받기 - Receiving

프로듀서

두 번째 프로그램인 receive.py는 큐에서 메시지를 받아 화면에 출력합니다. 이 프로그램도 RabbitMQ 서버에 연결해야 합니다. Rabbit에 연결하는 코드는 이전과 같습니다. 다음 단계는 이전과 마찬가지로 큐가 있는지 확인하는 것입니다. queue_declare를 사용하여 큐를 생성하는 것은 멱등수(idempotent)입니다 - 우리는 원하는 만큼 여러 번 명령을 실행할 수 있으며 하나만 생성됩니다.

channel.queue_declare(queue='hello')

큐를 다시 선언하는 이유를 물을 수 있습니다. 이전 코드에서 이미 큐를 선언했습니다. 큐가 이미 존재하는지 확신할 수 있으면 이를 피할 수 있습니다. 예를 들어 send.py program이 이전에 실행 된 경우입니다. 그러나 우리는 어느 프로그램을 먼저 실행할 지 아직 확실하지 않습니다. 이러한 경우에는 두 프로그램에서 큐를 반복하여 선언하는 것이 좋습니다.

참고 ! Listing queues

RabbitMQ에 포함 된 큐과 그 안에 있는 메시지의 수를 확인할 수 있습니다. rabbitmqctl 도구를 사용하여 (권한있는 사용자로) 할 수 있습니다.

sudo rabbitmqctl list_queues

큐에서 메시지를 받는 것이 더 복잡합니다. 콜백 함수를 큐에 등록하여 작동합니다. 메시지를 받을 때마다 이 콜백 함수는 Pika 라이브러리에 의해 호출됩니다. 우리의 경우 이 함수는 메시지 내용을 화면에 출력합니다.

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

다음으로, 우리는 RabbitMQ에게 이 특정 콜백 함수가 hello 큐로부터 메시지를 받아야 한다고 말할 필요가 있습니다.

channel.basic_consume(callback,
                      queue='hello',
                      no_ack=True)

이 명령이 성공하기 위해서는 구독하고자 하는 큐가 있는지 확인해야 합니다. 다행스럽게도 queue_declare를 사용하여 위의 큐를 생성했습니다. no_ack 매개 변수에 대해서는 나중에 설명합니다. 마지막으로 데이터를 기다리고 필요할 때마다 콜백을 실행하는 끊이지 않는 루프를 시작합니다.

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

전체코드

send.py:

#!/usr/bin/env python
import pika

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


channel.queue_declare(queue='hello')

channel.basic_publish(exchange='',
                      routing_key='hello',
                      body='Hello World!')
print(" [x] Sent 'Hello World!'")
connection.close()

receive.py:

#!/usr/bin/env python
import pika

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


channel.queue_declare(queue='hello')

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

channel.basic_consume(callback,
                      queue='hello',
                      no_ack=True)

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

이제 터미널에서 프로그램을 시험해 볼 수 있습니다. 먼저, 메시지를 기다리는 컨슈머를 시작합시다.

python receive.py
# => [*] Waiting for messages. To exit press CTRL+C
# => [x] Received 'Hello World!'

이제 프로듀서를 시작하십시오. 프로듀서 프로그램은 매 실행마다 중단됩니다.

python *send.py*
# => [x] Sent 'Hello World!'

축하드립니다! 우리는 RabbitMQ를 통해 첫 번째 메시지를 보낼 수 있었습니다. receive.py 프로그램이 자동으로 종료되지 않습니다. Ctrl-C로 중단 될 수 있습니다. 새 터미널에서 send.py를 다시 실행하십시오.

명명 된 큐에서 메시지를 보내고 받는 방법을 배웠습니다. 다음 포스트에서는간단한 작업 큐을 작성합니다.

튜토리얼 리스트