본문 바로가기

About/Flask

[Flask] 비동기 호출(태스크 큐, 토픽 큐, RabbitMQ)

비동기 호출

마이크로서비스 아키텍처에서 비동기 호출은 하나의 애플리케이션 안에서 처리했던 작업들이 여러 개의 마이크로서비스로 분리되면서 중심 역할을 담당한다. 비동기 호출은 마이크로서비스 앱 안의 분리된 스레드나 프로세스처럼 단순하게 동작할 수 있다. 즉, 동시에 일어나는 HTTP 요청/응답을 간섭하지 않고 작업을 처리한다.  하지만 동일한 파이썬 프로세스에서 직접 모든 것을 처리하는 것은 좋지 않다. 프로세스가 종료되거나 재시작되면 어떻게 해야하며, 서비스를 확장하는 경우에는 문제가 생길 수 있다.

이 방식보다는 다른 프로그램에 메시지를 보내서 처리하는 것이 더욱 안정적이다. 이를 통해 마이크로서비스가 본연의 목적, 즉 클라이언트에 응답을 보내는 것에 집중하게 할 수 있다,.

태스크 큐

Celery 워커에서 사용되는 패턴은 push-pull 태스크 큐이다.

어떤 서비스가 특정 큐에 메시지를 넣으면(push), 다른 워커가 메시지를 꺼내서(pull) 필요한 작업을 처리한다. 각 태스크는 단일 워커에 전달 된다.

태스크 큐

이 흐름은 양방향 커뮤니케이션이 아니다. 보내는 쪽에서는 큐에 메시지를 넣기만하며, 사용 가능한 워커는 메시지를 꺼낸다. 이와 같은 단방향 메시지 전달은 비동기 병렬 작업을 처리하기 좋고 확장도 쉽다.

한편 RabbitMQ와 같은 메시지 브로커는 메시지 영속성(persistence)를 제공한다. 따라서 메시지가 브로커에 추가된 이후에는 모든 워커가 오프라인이더라도 큐에 있는 메시지를 잃지 않는다.

토픽 큐

토픽(Topic)  큐는 태스크 큐의 변형이다. 여기서는 큐에 추가된 메시지를 무조건 가져오는 것이 아니라 관심 있는 특정 토픽만 구독해서 가져온다. 토픽은 메시지에 부착되는 이름표로 볼 수 있으며, 워커가 관심있는 메시지를 가져오기 위한 필터링 용도로 사용한다. 따라서 여러 개의 워커를 동일한 메시지 브러커에 등록해두고 각 워커가 특정 토픽 메시지만 전담하게 할 수 있다.

토픽 큐

Celery가 작업 큐를 만들 수 있는 좋은 도구 이지만 복잡한 메시지를 처리해야하는 경우 다른 RabbitMQ와 같은 다른 도구를 사용하는 것이 좋다

RabbitMQ

RabbitMQ 브로커는 TCP 서버의 일종으로 내부에 큐를 관리하며, RPC 호출을 통해 게시자에서 구독자로 메시지를 가져온다.

https://www.rabbitmq.com/

 

Messaging that just works — RabbitMQ

Developer Experience Deploy with BOSH, Chef, Docker and Puppet. Develop cross-language messaging with favorite programming languages such as: Java, .NET, PHP, Python, JavaScript, Ruby, Go, and many others.

www.rabbitmq.com

RabbitMQ는 AMQP(Advanced Message Queuing Protocol)을 구현했다. (https://www.amqp.org/)

AMQP는 queue, exchange, binding 이라는 세 개의 개념으로 구성된다.
- queue는 메시지를 보관하고 소비자가 메시지를 선택하기를 기다린다.
- exchange는 게시자가 새 메시지를 추가하기 위한 진입점이다.
- binding은 메시지가 exchange로 queue로 라우팅되는 방법을 정의한다.