RabbitMQ에서 메시지가 대기열에서 처리할 수 없는 메시지(소비자가 처리할 수 없는 메시지)가 되면 다른 교환으로 재경로되고, 이를 'dead letter 교환'이라고 합니다. 그런 다음 dead letter 교환은 dead letter 큐로 dead letter를 전달합니다.
Dead Letter Queue 그림 설명
위 그림은 dead letter 생성부터 처리까지의 전체 과정을 설명합니다.
Dead Letter 생성
다음은 dead letter가 생성되는 조건입니다:
- 메시지가 소비자에의해 명시적으로 거절될 때 (basic.reject / basic.nack)이며 requeue=false.
- 메시지의 TTL(생존기간)이 만료될 때.
- 대기열이 최대 길이에 도달했을 때.
Dead Letter Queue 처리 단계
- Dead letter 교환을 정의합니다 (이름에 속지 말고, 그냥 보통의 교환입니다, dead letter 처리에 관한 맥락에서만 그렇게 불립니다).
- Dead letter 교환에 바인딩할 큐를 정의합니다 (이 큐를 dead letter 큐라고 하며, 또한 보통의 큐입니다).
- Dead letter를 소비하기 위한 dead letter consumer를 정의합니다 (이름에 속지 말고, 이 또한 보통의 consumer입니다).
- Dead letter 교환을 지정된 큐에 바인딩합니다 (dead letter를 처리해야 하는 큐를 바인딩해야 합니다).
팁: 원칙에 대한 설명은 위의 그림을 참조하세요. 모든 프로그래밍 언어는 비슷한 방식으로 dead letter 큐를 처리합니다.
Golang에서 Dead Letter Queue 처리
1. Dead Letter 교환 정의
보통의 교환처럼 정의합니다.
// 교환을 선언합니다
err = ch.ExchangeDeclare(
"tizi365.dead", // 교환 이름
"topic", // 교환 종류
true, // 지속 가능
false,
false,
false,
nil,
)
2. Dead Letter 큐 정의
보통의 큐처럼 정의합니다.
// 큐를 선언합니다
q, err := ch.QueueDeclare(
"", // 큐 이름, 무작위로 생성하려면 비워두세요
false, // 지속 가능한 큐
false,
true,
false,
nil,
)
// 큐를 dead letter 교환에 바인딩합니다
err = ch.QueueBind(
q.Name, // 큐 이름
"#", // 라우팅 키, #은 모든 라우팅 키와 일치하며, 모든 dead letter 메시지를 수신함을 의미합니다
"tizi365.dead", // dead letter 교환 이름
false,
nil)
팁: dead letter 큐를 보통의 큐로 취급하세요.
3. Dead Letter Consumer 정의
// consumer를 생성합니다
msgs, err := ch.Consume(
q.Name, // 앞서 정의한 dead letter 큐 이름을 참조합니다
"", // consumer 이름, 제공하지 않으면 무작위로 생성됩니다
true, // 메시지 처리의 자동 승인
false,
false,
false,
nil,
)
// dead letter 큐로부터 메시지를 소비하기 위해 루프를 돌립니다
for d := range msgs {
log.Printf("Received dead letter message=%s", d.Body)
}
4. Dead Letter 교환을 특정 큐에 바인딩하기
// 큐 속성
props := make(map[string]interface{})
// dead letter 교환을 바인딩합니다
props["x-dead-letter-exchange"] = "tizi365.dead"
// 선택 사항: dead letter가 dead letter 교환에 전달될 때 라우팅 키를 설정합니다. 설정하지 않으면 원래 메시지의 라우팅 키를 사용합니다.
// props["x-dead-letter-routing-key"] = "www.tizi365.com"
q, err := ch.QueueDeclare(
"tizi365.demo.hello", // 큐 이름
true, // 지속 가능
false,
false,
false,
props, // 큐 속성 설정
)
이렇게 하면 tizi365.demo.hello 큐의 메시지가 dead letter가 되면 tizi365.dead dead letter 교환으로 전달됩니다.