/ PHP

RabbitMQ

서비스를 만들다보면 점점 Batch 작업을 해야할 경우가 증가하고, 때로는 큐 시스템을 통해 작업을 처리해야 하는 상황이 올 수 있다. 이럴 때 RabbitMQ 와 같은 Message Queue 솔루션을 사용할 수 있다. 많은 MQ 솔루션들이 있는데 ActiveMQ와 RabbitMQ를 고민하다가 증가하는 Google Trends 수치와 간단한 설명을 해둔 포스팅을 보고 내 서비스엔 RabbitMQ를 넣기로 결정했다.

설치

윈도우를 포함하여 웬만한 시스템은 모두 지원한다. 리눅스 기준으로 설치는 deb 파일로도 가능하지만, apt-get repository 에 추가하여 apt-get 으로 설치하는 방법이 좀 더 간편하며 설치는 공식 홈페이지의 가이드를 참고하면 쉽게 할 수 있다.

사용

기존에는 Redis 로 직접 구린 큐 시스템을 만들어서 돌렸었다. 1개의 Consumer 만이 존재하는 Queue 시스템 기반으로 쓰다가 여러개의 컨슈머를 지원하기 위해서 급하게 대충 수정해서 쓴거라, 비동기 방식인 레디스의 특성 때문에 여러 컨슈머들이 한개의 큐를 한번에 뽑아서 똑같은 작업을 하며 시간을 낭비하는 문제가 있었다. 이를 해결하기 위해서 RabbitMQ 를 도입했다. RabbitMQ에는 큐 사이즈를 제한하는 기능이 있다. 자바에서 사용법은 공식문서에서 볼 수 있고, 아래는 PHP에서 사용법이다.

$channel->queue_declare('task_queue', false, true, false, false, false, [
    'x-max-length' => ['I', 10]
]);

그러나 이 기능은 Max Queue Size 에 도달했을 때, 새로운 큐가 추가하는걸 제한하는 방식이 아닌 기존 큐 아이템중에서 제일 오래전에 추가된 아이템이 자동으로 큐에서 빠져나가도록 하는 방식이다. 내가 원하는 방식은 이미 큐에 들어간 아이템은 그대로 보존하면서, 새로운 아이템이 추가되는데 대한 제한을 두고 싶었으나 그런 기능은 존재하지 않았다.

그래서 기존 레디스에서 대충 Array 를 저장하는 방식으로 직접 만들어 쓰던 큐 시스템을 그대로 사용하고, 중간에 Exchanger 가 있어 여러개의 컨슈머가 이를 통해 받아쓰는 방식에 대해서만 RabbitMQ를 적용하기로 했다.

하지만 결국 레디스의 Pub/Sub 라는 기능을 써서 구현하는 것과 거의 다를바가 없는 상황이 됐다. (당시 대충 만들었을 땐 이 기능을 몰랐었음) 이미 RabbitMQ로 구현을 완료했으니 일단은 그대로 가기로 하고, 나중에 시간이 나면 RabbitMQ를 다시 없에고 레디스의 Pub/Sub 로 돌아갈 예정이다. </http:>