Skip to content
사고 기록
뒤로

RabbitMQ는 큐를 어떻게 Worker에게 배정할까

메시지 브로커를 처음 떠올릴 때, 나는 큐가 각 서버 엔드포인트로 요청을 보내는 그림을 떠올렸다. 순차적으로 HTTP를 날리되 비동기로 돌아가는 느낌. 그런데 알아보니 RabbitMQ의 기본 모델은 그 반대에 가까웠다. Worker가 먼저 붙어 있고, 브로커가 그 연결로 일을 배정한다.

전체 흐름, HTTP와의 차이, 그리고 큐 작업의 배정이 어떻게 이루어지는지 정리해봤다.

Table of contents

Open Table of contents

전체 흐름

Producer  --publish-->  Exchange  --route-->  Queue  --deliver-->  Worker
                                                         |
                                                      ack 후 제거

RabbitMQ 메시지 생명주기

역할하는 일
Producer메시지를 브로커에 맡김. Consumer를 모름
Exchange라우팅 규칙으로 어느 큐에 넣을지 결정
Queue메시지를 버퍼에 보관
Worker (Consumer)미리 연결해 두고, 받은 메시지를 처리한 뒤 ack
  • Producer 입장에서는 비동기이며 메시지를 맡기고 끝난다.
  • Worker는 자기 프로세스에서 핸들러를 실행한다.
  • 둘은 직접 연결되지 않고 브로커가 가운데서 중개한다.

HTTP와의 차이

HTTPRabbitMQ (기본)
연결요청마다 짧거나 statelessTCP/AMQP 연결을 유지
누가 먼저보통 클라이언트가 호출Worker가 먼저 구독
전달URL로 요청이미 열린 소켓에 write
프로토콜HTTPAMQP over TCP

관리 UI나 관리 API는 HTTP를 쓸 수 있다. 다만 그건 메시지 배정 경로와는 별개다. “큐가 일을 나눈다”고 말할 때의 통신은 기본적으로 AMQP다.

배정이 실제로 하는 일

ready인 Worker 소켓을 고른 뒤, 그 연결에 메시지 프레임을 보낸다.

배정: 등록 후 소켓에 deliver

  1. Worker 실행 → TCP/AMQP 연결 → basic.consume(queue)로 구독
  2. 브로커 메모리에 Consumer Table 유지 (socket/channel, unacked, prefetch, ready 여부)
  3. 큐에 메시지 도착 → ready consumer 선택 (기본은 round-robin + QoS/prefetch)
  4. 선택된 소켓에 basic.deliver + 페이로드 write
  5. Worker 핸들러 실행 → ack → 큐에서 제거, unacked 감소

브로커 내부 Consumer Table

[연결 유지]
Worker  <-—— TCP / AMQP socket ——->  RabbitMQ

메시지 도착 시
RabbitMQ  -- deliver + payload -->  Worker
Worker    -- ack ---------------->  RabbitMQ

알림만 주고 Worker가 다시 받으러 가는 구조가 아니다. 같은 소켓으로 작업 데이터까지 전달된다.

prefetch

  • prefetch=1: 미ack 상태면 그 Worker는 잠시 건너뛴다.
  • prefetch가 크면 한 Worker가 메시지를 미리 많이 받을 수 있다.

순서

  • 큐 자체는 대체로 FIFO다.
  • Worker가 여러 대면 서로 다른 메시지를 병렬로 처리한다.

옵저버 / Pub-Sub과의 관계

아이디어는 옵저버와 비슷하다. 하지만 발행/구독, 느슨한 결합. 다만 브로커는 중개자, 네트워크, 버퍼, ack, 재시도, 프로세스 분리까지 포함한다.

그래서 RabbitMQ를 그냥 Pub/Sub이라고만 부르기엔 작은 단위다.

Work Queue와 Fanout Pub/Sub

모드동작용도
Work Queue메시지 1개 → Consumer 중 1명만같은 작업을 나눠 처리
Fanout Pub/Sub이벤트 1개 → 구독 큐마다 복사여러 시스템이 각자 처리

짧게 말하면 이렇게 정리할 수 있다.

  • 옵저버: 직접 호출한다.
  • 브로커: 큐에 넣으면 연결된 쪽이 받아서 실행한다.

HTTP가 아닌 AMQP

오해실제
큐가 각 서버에 순차 HTTP 요청열린 AMQP 소켓으로 deliver
알림만 주고 Worker가 다시 조회페이로드가 같이 옴
전역이 한 줄로 한 명씩만큐 순서는 지키되, Worker 여러 대면 병렬

한 줄 정리

RabbitMQ는 Worker HTTP 엔드포인트를 호출하지 않는다. Worker가 먼저 AMQP 소켓으로 붙어 있고, 브로커가 그 연결로 메시지를 보내 배정한다.