RabbitMQ 브로커가 재시작되면 큐에 쌓여 있던 메시지는 전부 사라질까, 아니면 살아남을까?

메시지 지속성과 생명주기 관리

왜 메시지 지속성이 중요한가

RabbitMQ에서 메시지 지속성(Persistence)이란 브로커 재시작이나 장애 상황에서도 메시지가 손실되지 않고 보존되는 것 을 의미합니다.

결제, 예약, 주문 처리와 같이 신뢰성이 중요한 비즈니스에서는 하드웨어 장애, 네트워크 문제, 또는 브로커 재시작으로 인한 메시지 손실이 치명적인 결과를 초래합니다. 따라서 메시지의 중요도에 따라 적절한 지속성 정책을 적용하는 것이 필수적입니다.

**핵심 : 메시지 지속성은 Durable(큐/익스체인지 속성)과 Persistent(메시지 속성) ** 두 가지를 모두 설정해야 완전하게 보장됩니다. 이 둘은 서로 다른 대상에 적용되는 별개의 설정입니다.


Durable vs Persistent — 무엇이 다른가

실무에서 가장 많이 혼동하는 부분이 바로 Durable과 Persistent의 차이입니다. 한 문장으로 정리하면 다음과 같습니다.

  • Durable = ** 큐/익스체인지 **의 지속성 (컨테이너가 살아남는가)
  • Persistent = ** 메시지 **의 지속성 (내용물이 살아남는가)

Durable (큐/익스체인지 지속성)

Durable 속성이 true인 큐 또는 익스체인지는 ** 브로커가 재시작되어도 사라지지 않습니다.** 기본값은 false이므로, 명시적으로 설정해야 합니다.

익스체인지 생성 시 Durable 설정

JAVA
/**
 * @param exchange 익스체인지 이름
 * @param type     익스체인지 타입 ("direct", "fanout", "topic", "headers")
 * @param durable  true이면 브로커 재시작 시에도 익스체인지가 유지됨
 */
exchangeDeclare(String exchange, String type, boolean durable)

큐 생성 시 Durable 설정

JAVA
/**
 * @param queue      큐 이름
 * @param durable    true이면 브로커 재시작 시에도 큐가 유지됨
 * @param exclusive  true이면 해당 커넥션에서만 사용 가능
 * @param autoDelete true이면 모든 소비자 연결 해제 시 자동 삭제
 * @param arguments  기타 큐 옵션 (TTL 등)
 */
queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments)

Durable을 true로 설정하면 큐 자체는 보존되지만, 큐 안에 저장된 메시지가 보존되는 것은 아닙니다. 메시지까지 보존하려면 Persistent 설정이 별도로 필요합니다.


Persistent (메시지 지속성)

Persistent 속성이 true인 메시지는 ** 디스크에 저장 **되어 브로커 재시작이나 장애 상황에서도 사라지지 않습니다. 기본값은 false(메모리에만 저장)입니다.

메시지 발행 시 Persistent 설정

JAVA
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.MessageProperties;

// 방법 1: Builder 패턴
AMQP.BasicProperties props = new AMQP.BasicProperties.Builder()
    .deliveryMode(MessageProperties.PERSISTENT_TEXT_PLAIN.getDeliveryMode()) // deliveryMode=2
    .build();
channel.basicPublish("my_exchange", "my_routing_key", props, "Hello, RabbitMQ!".getBytes("UTF-8"));

// 방법 2: 미리 정의된 상수 사용
channel.basicPublish("", "task_queue",
    MessageProperties.PERSISTENT_TEXT_PLAIN,  // Persistent 속성 적용
    message.getBytes("UTF-8")
);

AMQP.BasicPropertiesnull을 전달하면 메시지는 기본적으로 비지속성(deliveryMode=1)으로 처리되어 ** 메모리에만 저장 **됩니다.


Durable과 Persistent 조합 가이드

Durable (큐)Persistent (메시지)브로커 재시작 시 동작적합한 시나리오
truetrue큐와 메시지 모두 디스크에 보존 (가장 안전)결제, 주문 등 신뢰성 필수
truefalse큐는 유지되나 메시지는 유실큐 구조는 유지하되 메시지 손실 허용
falsetrue큐 자체가 사라지므로 메시지도 함께 유실(비권장) 실질적 효과 없음
falsefalse큐와 메시지 모두 유실임시 데이터, 캐시성 메시지

** 정리 **: 메시지의 신뢰성을 보장하려면 Durable과 Persistent를 모두 true로 설정 해야 합니다. 한쪽만 true여도 장애 상황에서 메시지가 유실될 수 있습니다.

설정 결정 흐름

PLAINTEXT
메시지 손실이 허용되는가?
├─ Yes → Durable=false, Persistent=false (최고 성능)
└─ No → 메시지가 반드시 보존되어야 하는가?
       ├─ Yes → Durable=true, Persistent=true (최고 안전성)
       └─ 큐 구조만 유지하면 됨 → Durable=true, Persistent=false

TTL (Time To Live)

TTL은 메시지 또는 큐에 저장된 데이터의 유효 기간을 제한 하는 기능입니다. 만료된 메시지는 자동으로 삭제되며, DLX가 설정되어 있으면 Dead Letter Queue로 이동합니다.

큐 TTL vs 메시지 TTL

비교 항목큐 TTL메시지 TTL
설정 위치큐 선언 시 x-message-ttl 인자메시지 발행 시 expiration 속성
** 적용 범위**해당 큐에 들어오는 ** 모든 메시지**** 개별 메시지**
** 유연성**일괄 적용 (큐 단위)메시지별 개별 설정 가능
** 활용 예**로그 큐에 1시간 TTL 일괄 적용VIP 메시지는 24시간, 일반은 1시간

큐 TTL 설정 코드

JAVA
Map<String, Object> args = new HashMap<>();
args.put("x-message-ttl", 30000); // 30초 (밀리초 단위)

channel.queueDeclare(
    "my_queue",  // 큐 이름
    true,        // durable
    false,       // exclusive
    false,       // autoDelete
    args         // arguments (TTL 포함)
);

메시지 TTL 설정 코드

JAVA
AMQP.BasicProperties props = new AMQP.BasicProperties.Builder()
    .deliveryMode(MessageProperties.PERSISTENT_TEXT_PLAIN.getDeliveryMode())
    .expiration("10000") // 10초 후 자동 삭제 (문자열로 지정)
    .build();

channel.basicPublish("", "task_queue", props, "Hello, RabbitMQ!".getBytes("UTF-8"));

큐 TTL과 메시지 TTL을 동시에 설정한 경우

두 TTL 중 ** 더 짧은 값이 우선 적용 **됩니다.

큐 TTL메시지 TTL적용되는 TTL
30초10초10초 (메시지 TTL이 더 짧음)
10초30초10초 (큐 TTL이 더 짧음)
미설정10초10초 (메시지 TTL만 적용)
30초미설정30초 (큐 TTL만 적용)

따라서 메시지 TTL을 활용하려면 큐 TTL을 메시지 TTL보다 길게 설정하는 것이 좋습니다.


Auto-delete (자동 삭제)

Auto-delete는 ** 큐나 익스체인지가 더 이상 사용되지 않을 때 자동으로 삭제되는 기능 **입니다.

대상삭제 조건
큐 (autoDelete=true)연결된 ** 모든 소비자가 연결을 해제 **했을 때 자동 삭제
익스체인지 (autoDelete=true)바인딩된 ** 모든 큐가 해제 **되었을 때 자동 삭제

** 주의 **: Auto-delete는 임시 큐나 익스체인지에 적합합니다. 중요한 데이터를 처리하는 큐에는 autoDelete=false로 설정하여 예기치 않은 삭제를 방지해야 합니다.


요약

속성적용 대상역할기본값
Durable큐, 익스체인지브로커 재시작 시 구조 보존false
Persistent메시지브로커 재시작 시 메시지 보존false
TTL큐 또는 메시지유효 기간 초과 시 자동 삭제무제한
Auto-delete큐, 익스체인지사용자 없을 때 자동 삭제false

주의할 점

Durable만 설정하고 Persistent를 빠뜨리는 실수

가장 흔한 실수입니다. 큐를 Durable로 만들어 놓고, 메시지 발행 시 Persistent를 설정하지 않으면 브로커 재시작 후 큐는 남아 있지만 메시지는 전부 사라집니다. 두 설정은 각각 다른 대상(큐 vs 메시지)에 적용되는 별개의 옵션이라는 점을 반드시 기억해야 합니다.

Auto-delete 큐에 중요 데이터를 넣으면 안 된다

Auto-delete가 켜진 큐는 마지막 소비자가 연결을 끊는 순간 자동으로 삭제됩니다. 소비자를 재시작하는 짧은 순간에도 큐 자체가 사라질 수 있으므로, 결제나 주문 같은 중요 데이터에는 절대 사용하면 안 됩니다.


신뢰성이 중요한 시스템에서는 Durable=true + Persistent=true 를 기본으로 설정하고, TTL과 Auto-delete는 비즈니스 요구사항에 맞게 선택적으로 적용하는 것을 권장합니다.

**공식 문서 참고 **: TTL | Queues

댓글 로딩 중...