오늘은 Celery 와 가장 잘 맞는 호흡을 자랑하는 RabbitMQ를 


파이썬과 어떻게 활용할 수 있는지 정리해보겠습니다.



서비스가 확장함에 따라서 본 application의 load를 분산하기 위해서 broker와 worker 를 도입하게 됩니다. 


그 중에서 broker는 본 application(producer) 에게 task를 받아서 worker 에게 전달하는 중계 역할을 하는 소프트웨어 입니다.



Broker를 우체국으로 자주 비유하기도 합니다.


보내는 사람에게 메세지를 받아서 받는 사람에게 전달해주는 역할을 하게 되는거죠.



보통 worker는 celery를 많이 사용하지만 본 포스팅에서는 python으로 worker 를 만들도록 하겠습니다.





출처: RabbitMQ 공식 홈페이지



RabbitMQ에서 메시지를 보관하는 방법으로 Queue 자료구조 방식을 사용합니다. 쉽게 말해 우체통입니다.



가장 간단한 예제를 만들어 보겠습니다.


본 예제에서는 실제서비스와 유사하게 만들기 위해서 로컬 서버가 아닌 aws ec2에 RabbitMQ를 설치하여 실습하도록 하겠습니다.



1) 먼저 실습을 위해서 AWS에서 EC2 를 생성합니다.


AMI (Aws machine Image) 는 Ubuntu 16.04 를 선택했고, ssh 접속을 위해서 key를 만들어 줍니다.


또한, 외부 접속을 위해서 필요한 inbound 규칙을 셋팅해줘야 합니다.


ssh로 ec2 서버에 접속 후에 rabbitmq를 설치하는 과정은 



https://openmind8735.com/aws/rabbitmq/2017/07/17/AWS-EC2%EC%97%90-RabbitMQ-%EC%84%9C%EB%B2%84%EC%98%AC%EB%A6%AC%EA%B8%B0/


해당 블로그에 잘 소개가 되어 있어 링크를 남깁니다.




2) 이제 local 환경에서 해당 rabbitmq-server에 메세지를 보내는 파이썬 코드와 받는 파이썬 코드를 만듭니다.


pika 공식 Docs: https://pypi.python.org/pypi/pika


먼저 rabbitmq와 python 프로세스 간의 통신을 위해 python client library 인 pika를 설치합니다.



- pika를 설치합니다.


pip3 install pika


- pika를 이용해서 rabbitmq와 연결합니다.


먼저 producer에서 메세지를 보내는 코드 부터 확인해보겠습니다.


import pika


# rabbitmq 서버와 연결합니다.
connection = pika.BlockingConnection(pika.URLParameters('amqp://rabbitmq_id:rabbitnq_password@ec2-xx-xxx-xxx-xxx.ap-northeast-2.compute.amazonaws.com/rabbitmq_vhost))


# 해당 rabbitmq와 통신할 수 있는 channel을 만듭니다.

channel = connection.channel()

# hello 라는 이름을 가진 queue를 생성합니다.
channel.queue_declare(queue='hello')

# 해당 queue에 3초 간격으로 메시지를 전송합니다.
for i in range(10):
channel.basic_publish(exchange='',
routing_key='hello',
body='Hello World!')
print(" [x] Sent 'Hello World!'")
time.sleep(3)

connection.close()



이제 메세지를 받아서 task를 수행하는 코드를 알아보겠습니다.


import pika

# 프로듀서와 같이 rabbitmq와 연결을 위한 코드를 추가합니다.
connection = pika.BlockingConnection(pika.URLParameters('amqp://rabbitmq_id:rabbitnq_password@ec2-xx-xxx-xxx-xxx.ap-northeast-2.compute.amazonaws.com/rabbitmq_vhost))


# 다시 한 번 hello라는 큐를 생성하는 이유는 producer와 consumer중에 어떤 프로세스가 먼저 실행될지 모르기 때문에

# 안전하게 두 곳 모두 해당 코드를 넣어줍니다.
channel.queue_declare(
queue='hello')

# 메시지를 받으면 실행할 task(함수)를 정의합니다.
def callback(ch, method, properties, body):
print(" [x] Received %r" % body)
print("저는 worker입니다. 본 application의 load를 분산시켜드리겠습니다.")
ch.basic_ack(
delivery_tag=method.delivery_tag)


# consumer로 설정하여 queue로 부터 메시지를 받아 task를 수행할 수 있도록 합니다.
channel.basic_consume(callback,
queue='hello',
)

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



해당 ec2 서버에가서


sudo rabbitmq-server 명령어를 통해 rabbitmq를 실행시킵니다.



그리고 send.py (메세지를 보내는 파이썬 파일)과 recieve.py (task를 수행하는 파이썬 파일)을 실행시킵니다.


다음과 같은 결과를 확인할 수 있습니다.

지금까지 RabbitMQ를 이용해서 broker를 다른 서버에 만들어서 rabbitmq 에서 메세지를 보내고 받아서 task를 수행하는 예제를 수행했습니다.


아직 공부해야할 내용이 많습니다. 



참고자료:


https://www.rabbitmq.com/tutorials/tutorial-one-python.html (아주 잘 예제가 설명되어 있습니다. 영어로 되어 있어서 해당 포스팅과 같이 보면 도움이 될 것 입니다.)



rabbitmq가 비정상적으로 종료되서 메세지를 잃어버리거나 , 


worker가 메세지를 받아서 수행하던 중 비정상적으로 종료되


는 경우 등 더 필요한 사항에 대해서 더 알아보는 포스팅을 만들어 보도록 하겠습니다.


감사합니다.







'프로그래밍 > 아키텍쳐' 카테고리의 다른 글

파이썬에서 RabbitMQ 활용하기 1편 Using Pika  (0) 2018.02.14

+ Recent posts