들어가기 앞서
이전 포스팅에서 간단하게 언급하기는 하였지만, 메시징 시스템을 구성함에 있어 중요한 부분은 컨슈머가 메시지를 처리에 실패 했을 경우 어떻게 처리할 것인지에 대한 방안을 마련하는게 중요하다고 생각합니다.
그래서 오늘은 DLQ, DLX, PLQ에대해 알아볼 예정입니다.
- DLX (Dead Letter Exchange) : 죽은 메시지(dead letter)를 받는 특수한 Exchange
- DLQ (Dead Letter Queue) : DLX를 통해 전달된 실패 메시지를 저장하는 큐
- PLQ (Parking Lot Queue) : DLQ에서 재처리를 시도했지만 계속 실패한 메시지를 별도로 보관하는 큐

DLX (Dead Letter Exchange)

DLX는 실패한 메시지를 받는 특수한 Exchage 입니다. Queue에 있던 메시지가 특정 조건에 의해 실패하게 되면, DLX로 라우팅 되게 됩니다.
DLX 라우팅 조건
- Consumer가 basic.reject() 혹은 basic.nack(requeue=false)로 거부한 경우
- 메시지의 TTL이 초과한 경우
- Queue의 메시지가 가득 찼을 경우
- 재시도 제한 횟수가 초과한 경우
DLQ (Dead Letter Queue)

DLQ는 DLX를 통해 전달된 실패 메시지를 저장하는 큐 입니다. DLQ를 사용하는 이유는 리큐잉(requeue)가 가능하도록 설정한 경우, 컨슈머가 메시지 처리에 실패 했을때, 무한정 실패를 반복하는 과정을 방지할 수 있습니다. 또한 실패 메시지에 대한 해결 방안 전략을 마련 할 수 있습니다. 또한 비즈니스 로직 장애 및 서버 장애등 의도치 않은 상황으로 인해 메시지 처리를 실패 했을때 재처리, 수동 확인, 분석등이 가능합니다.
Retry
Retry는 일종의 DLQ를 담당하는 Consumer라고 생각하시면 됩니다. DLQ에 적재된 메시지를 재처리 과정을 통해 다시 정상적인 Exchange 전략과 Queue로 메시지를 다시 보내, 정상 흐름으로 복귀시키는 구조입니다.
PLQ (Parking Lot Queue)

DLQ의 Retry에서 재시도한 메시지가 여러 번 실패하면, 더 이상 무한 루프에 빠지지 않도록 재처리하지 않고 PLQ에 따로 보관하게 됩니다. 이렇게 보관된 메시지는 관리자에 의해 확인하고 수동으로 처리하게 됩니다. 즉, 더 이상 메시지를 재처리하는게 의미가 없으며, 재처리 해봤자 무한히 실패만 하는 메시지들을 모아 두는 곳입니다. 따라서 사람의 수동 작업을 통해 새로운 메시지를 생성하여 처리하도록 해야 합니다.
Retry Template
RetryTemplate은 Spring AMQP에서 메시지를 전송하거나 처리할 때 일시적인 실패에 대해 재시도 로직을 적용할 수 있도록 도와주는 컴포넌트 입니다.
RabbitMQ 서버가 일시적으로 연결이 끊겼다거나, 네트워크 지연, 브로커 장애 등으로 인해 메시지 전송/처리가 실패하는 경우가 있을 수 있습니다. 이럴 때 한 번만 시도하고 포기하면 복구 불가능한 장애로 이어질 수 있기 때문에, 재시도 정책을 통해 안정성을 높일 수 있습니다.
코드 레벨에서 설정
@Configuration
public class RetryConfig {
@Bean
public RetryTemplate retryTemplate() {
RetryTemplate retryTemplate = new RetryTemplate();
SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
retryPolicy.setMaxAttempts(3);
FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
backOffPolicy.setBackOffPeriod(1000L);
retryTemplate.setRetryPolicy(retryPolicy);
retryTemplate.setBackOffPolicy(backOffPolicy);
return retryTemplate;
}
}
application.yml에서 설정
spring:
rabbitmq:
host: localhost
port: 5672
username:
password:
listener:
simple:
retry:
enabled: true # 재시도 활성화
initial-interval: 1000 # 첫 재시도 대기 시간 1초
max-attempts: 3 # 최대 재시도 횟수
max-interval: 1000 # 최대 대기시간
default-requeue-rejected: false
application.yml을 사용하면 코드를 조금더 깔끔하게 작성할 수 있어, application.yml을 통해 관리하는 것을 저는 선호 합니다.
Reference
https://kjy042386.tistory.com/547
'Kafka, RabbitMQ' 카테고리의 다른 글
| RabbitMQ에 대해 알아보자 - (6) Exchange 전략 (0) | 2025.05.05 |
|---|---|
| RabbitMQ에 대해 알아보자 - (5) Work Queue를 통한 분산처리 (0) | 2025.05.03 |
| RabbitMQ에 대해 알아보자 - (3) 메시지 처리에 실패하게 된다면? (0) | 2025.04.30 |
| RabbitMQ에 대해 알아보자 - (2) RabbitMQ vs Kafka (0) | 2025.04.30 |
| RabbitMQ에 대해 알아보자 - (1) 간단한 이해 (0) | 2025.04.22 |