본문 바로가기
기술, 개발/RabbitMQ

RabbitMQ 개념

by Jaejin Sim 2025. 9. 10.
반응형

 RabbitMQ 는 AMQP를 구현한 미들웨어 다양한 언어를 지원하여 인기가 많다

RabbitMQ 예제코드를 작성하고 테스트하면서 제 나름대로 이해하기위해 정리하였습니다. 문서에 대한 설명이 빈약할 수 있으니 양해 바랍니다.

AMQP

  • 메세지 지향 미들 웨어를 위한 표준 응용 계층 프로토콜

구조

크게 보면 3개로 구분 지을 수 있다

프로듀서 (P)

  • 메세지를 큐에 보낸다

컨슈머 (C)

  • 큐에 있는 메세지를 받는다

큐 (hello)

  • 메세지를 담는다
  • 큐는 이름을 정할 수 있다 (hello)

메소드 설명

이름  설명
queue_declare() 큐가 없으면 생성
exchange_declare() exchange 없으면 생성
queue_bind() exchange 와 큐를 연결함
basic_publish() 메세지 큐에 전달
basic_consume() 큐에서 메세지 받기

메세지를 큐에 보낸다 (producer)

  • 메세지를 담을 큐가 있어야 한다.
  • 큐가 없으면 queue_declare를 호출 하여 큐를 생성 한다.
  • basic_publish() 사용하여 메세지를 큐에 보낸다.
<?php

require_once __DIR__ . '/vendor/autoload.php';
use PhpAmqpLib\\Connection\\AMQPStreamConnection;
use PhpAmqpLib\\Message\\AMQPMessage;

$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();

$channel->queue_declare('hello', false, false, false, false);

$msg = new AMQPMessage('Hello World!');
$channel->basic_publish($msg, '', 'hello');

echo " [x] Sent 'Hello World!'\\n";

$channel->close();
$connection->close();
?>

queue_declare() 인수 설명

  • 큐가 존재하지 않으면 큐를 생성한다
// hello 라는 이름의 큐 선언
/*
name: 큐 이름 (hello)
passive: false
durable: true // the queue will survive server restarts
exclusive: false // the queue can be accessed in other channels
auto_delete: false //the queue won't be deleted once the channel is closed.
*/
$channel->queue_declare('hello', false, false, false, false);

인수  설명  비고
name 큐 이름 amq로 시작하는 큐이름은 생성 할 수 없다
passive true : hello 라는 큐가 있으면 Queue.declare_ok 없으면 오류
false : hello 라는 큐가 없으면 생성해줌
 
durable ture : RabbitMQ 서버가 다시 시작 되도 큐는 살아있음
false : 서버가 죽으면 큐도 삭제됨
 
exclusive true : 배타적 큐 선언 (임시큐)
프로세스 (프로듀서, 컨슈머)가 종료되면 큐 삭제됨
독립적인 큐 혼자 쓸건지
프로듀서는 단발성으로 프로세스가 바로 종료 되기때문에
배타적큐 선언은 컨슈머에서 선언해야함
auto_delete true : 컨슈머의 채널이 닫혔을 때 큐 삭제됨

false : 컨슈머의 채널이 닫혀도 큐는 삭제 안됨
 
  • 큐 이름이 빈 값 이면 이름을 자동으로 생성함. ex)amq.gen-JzTY20BRgKO-HjmUJj0wLg
  • 최초 실행하면 RabbitMQ에 hello 라는 큐가 없기때문에 큐를 먼저 생성해줍니다.
  • 어드민에서 hello 라는 큐가 생성된 걸 볼 수 있음

참고!!

// 처음에 아래와 같이 hello 큐를 생성
$channel->queue_declare('hello', false, false, false, false);

// 만약 옵션 값을 변경 한다면 ??
$channel->queue_declare('hello', false, true, false, false); // 오류 발생!!!

이미 hello 라는 큐가 있어서 오류 발생함.
이럴 때는 큐이름을 변경 하던가, 어드민에서 hello 큐를 삭제 해야 함

basic_publish() 인수 설명

basic_publish에서 직접! 큐로 메세지를 담을 수 없다.

큐에 메세지를 담기 위해선 exchange를 사용 해야함

// 큐에 메세지를 보낸다
$channel->basic_publish($msg, '', 'hello');
인수  설명
$msg 큐에 담길 메세지
‘’ exchange 이름
hello route key
exchange 이름을 지정하지 않으면 exchange 는 default exchange 를 사용한다
default exchange 는 direct 방식이며, route key 는 큐 이름과 동일하다

default exchange

큐에 있는 메세지를 받는다 (Consumer)

<?php

require_once __DIR__ . '/vendor/autoload.php';
use PhpAmqpLib\\Connection\\AMQPStreamConnection;

$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();

$channel->queue_declare('hello', false, false, false, false);

echo " [*] Waiting for messages. To exit press CTRL+C\\n";

$callback = function ($msg) {
    echo ' [x] Received ', $msg->body, "\\n";
    $msg->ack();
};

$channel->basic_consume('hello', 'ConsumerTag', false, false, false, false, $callback);

while ($channel->is_open()) {
    $channel->wait();
}

$channel->close();
$connection->close();
?>

basic_consume() 인수 설명

/*
    queue: Queue from where to get the messages
    consumer_tag: Consumer identifier
    no_local: Don't receive messages published by this consumer.
    no_ack: If set to true, automatic acknowledgement mode will be used by this consumer. See <https://www.rabbitmq.com/confirms.html> for details.
    exclusive: Request exclusive consumer access, meaning only this consumer can access the queue
    nowait:
    callback: A PHP Callback
*/
$channel->basic_consume('hello', 'ConsumerTag', false, false, false, false, $callback);

 

인수  설명
queue 사용할 큐 이름 지정
consumer_tag 컨슈머 식별자 (단순 텍스트).
빈 값이면 자동생성
no_local true : 메시지를 게시한 연결로 메시지를 보내지 않습니다.
(no_local 플래그는 RabbitMQ에서 지원되지 않습니다.)
no_ack true : 자동으로 ack() 처리
false : 수동으로 ack() 호출 해야함
exclusive trure: 독점 컨슈머 . 해당 컨슈머만 큐에 엑세스 할 수 있다. → 체크해보고
다른 컨슈머는 해당 큐에 접근할 수 없다
nowait async 모드로 동작할지에 대한 여부 (뭔지 모르겠음)
false일 경우, 서버에 요청하고 그에 대한 결과를 받은 이후에 함수가 종료
true : 서버에 요청하고, 즉시 함수가 종료
callback 콜백 함수 → 여기서 메세지 받기 처리함

ack() ?

$msg→ack()

 

  • 메세지를 정상적으로 받았는지 컨슈머는 RabbitMQ 서버에 ok 응답 해줘야 함
  • ack() 호출 하지 않으면 작업은 처리 했는데 unacked 임

  • ack 는 ? 정상적으로 처리 완료 되었어요. 하고 RabbitMQ에 알려 주는 것
  • 만약 컨슈머가 강제 종료 되었을 경우( ack() 호출하지 않은 메세지)
  • 다시 ready 로 넘어가서 컨슈머 재 실행 시 메세지 재 발송 처리함

Queue exchange bind

exchange 선언 (생성)

/*
    name: $exchange
    type: direct
    passive: false
    durable: true // the exchange will survive server restarts
    auto_delete: false //the exchange won't be deleted once the channel is closed.
*/
$channel->exchange_declare('Route', AMQPExchangeType::DIRECT, false, true, true);

 

인수  설명
name exchange 이름
type 4개의 타입이 있음
passive true : exchange (name)가 없으면 예외 발생. 있으면 아무것도 하지 않음
false : 없으면 새로 선언
durable ture : RabbitMQ 서버가 다시 시작 되도 exchange 는 살아있음
false : 서버가 죽으면 exchange 도 삭제됨
auto_delete true : 해당 큐에 대한 바인딩이 끊기고 해당 큐를 참조 하는 컨슈머의 채널이 닫히면 exchange 는 삭제됨
큐 auto_delete = true 해줘야 역할을 제대로 할 수 있음
(어드민에서 수동으로 바인딩을 끊지 않으면 해당 exchange 는 계속 살아있음)

auto_delete 예시

/*
큐는 auto_delete = false
exchange는 auto_delete = true
*/
$channel->exchange_declare('direct_logs','direct', false,false,true);
$channel->queue_declare('testq2', false, false, false, false);
$channel->queue_bind('testq2', 'direct_logs');

큐 (testq2) 에 direact_logs exchange 바인딩 되어있음

testq2 → auto_delete = false

direact_logs → auto_delete = true

컨슈머 종료 했을 때

direct_logs excahgne 삭제 되지 않고 살아있음

수동으로 testq2 unbind 시 direct_logs 삭제된 부분 확인 가능

/*
큐는 auto_delete = true
exchange는 auto_delete = true
*/
$channel->exchange_declare('direct_logs','direct', false,false,true);
$channel->queue_declare('testq2', false, false, false, true);
$channel->queue_bind('testq2', 'direct_logs');

컨슈머 실행

컨슈머 종료

큐랑 익스체인지 둘다 삭제 되어있음

반응형

'기술, 개발 > RabbitMQ' 카테고리의 다른 글

Dead Letter Exchange (메세지 만료)  (0) 2025.09.10
컨슈머 병렬 처리, 메세지 손실 방지  (0) 2025.09.10
Queue and Exchange  (0) 2025.09.10
RabbitMQ 최신 버전 우분투 설치  (0) 2025.09.10
RabbitMQ 도커 설치  (0) 2025.09.10