RabbitMQ 튜토리얼 살펴보기 (1) - Hello World

RabbitMQ

  • 메세지 브로커로 메세지를 받고 전달
  • producer
    • 메세지를 보내는 프로그램
  • queue
    • RabbitMQ 내부의 메세지를 저장하는 공간
    • 호스트의 메모리와 디스크 한도에 의해서만 제한
    • 기본적으로 큰 메세지 버퍼
    • 많은 프로듀서가 하나의 큐에 가는 메세지를 보낼 수 있고 많은 컨슈머가 하나의 큐에서 데이터를 받을 수 있음
  • consumer
    • 메시지를 받기 위해 기다리는 프로그램
  • 프로듀서, 컨슈머, 브로커가 같은 호스트에 있지 않아도 됨
  • 어플리케이션은 프로듀서와, 컨슈머 모두 될 수 있음

Hello World Tutorial

  • Prerequisites

    • RabbitMQ
      docker run -it --rm --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3.9-management
    
    • python client
    • 가상환경을 만들고 라이브러리 설치
      python -m venv venv
      source venv/bin/activate
      (venv) pip install pika
    

Producer

프로듀서 역할을 하는 send.py를 만들어 큐에 메세지를 담아서 보내보도록 한다. 예제의 #1에서는 localhost에 연결을 하지만 브로커나 다른 머신에 연결하고 싶을 때는 이름이나 IP주소를 명시해주면 된다. 메세지를 보내기 전에는 큐기 있는지 확인해야 한다. 큐가 없을 때 메세지를 보내게 되면 분실된다. #3에서 메세지를 보낼 큐를 생성하도록 한다.

RabbitMQ에서는 메세지는 항상 exchange를 지나서 큐에 들어가게 된다. 예제에서는 exchange에 빈 문자열을 넣어 정확히 어떤 큐에 보낼지를 명시하도록 한다. 메세지를 보낼 큐의 이름은 routing_key에 적도록 한다.

# send.py
import pika


connection = pika.BlockingConnection(pika.ConnectionParameter('localhost')) # 1
channel = connection.channel() # 2
channel.queue_declare(queue='hello') # 3
channel.basic_publish(exchange='', routing_key='hello', body='Hello World!') #4

connection.close()

Consumer

send.py에서 보내는 메세지를 큐에서 받을 컨슈머는 receive.py에 만들도록 한다. 여기서도 RabbitMQ에 연결하고 큐를 만드는 부분은 위와 같다. 프로듀서와 컨슈머 중 어떤 프로그램이 먼저 실행될지 알 수 없으므로 큐는 양쪽에 항상 선언하도록 한다. 컨슈머에서는 메세지를 가져오면 콜백 함수에 가게 된다. 메세지를 받을 때마다 콜백 함수가 실행되며 예제에서는 메세지를 출력하도록 했다. Try-except 구문에서는 프로그램을 종료하기 위해 KeyboardInterrupt

import os
import sys

import pika


def main():
    connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
    channel = connection.channel()

    channel.queue_declare(queue='hello')

    def callback(ch, method, properties, body):
        print(f'Received {body}')

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

    print('wating for messages')
    channel.start_consuming()


if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        print('exit')
        try:
            sys.exit(0)
        except SystemExit:
            os._exit(0)

Test

먼저 도커에서 rabbitmq 서버를 띄운 후에 send.py를 실행해서 메세지를 보내도록 한다. 그 후에 receive.py를 실행하면 컨슈머가 메세지를 가져와서 콜백 함수에서 출력하는 것을 볼 수 있다.