RabbitMQ는 지연 메시지를 네이티브로 지원하지 않습니다. 현재 주요 구현 방법으로는 데드레터 익스체인지 + 메시지 TTL 방식이나 rabbitmq-delayed-message-exchange 플러그인이 있습니다.

지연 큐의 사용 사례

  • 메시지 생성 및 소비에 대한 시간 창 요구 사항이 있는 시나리오. 예를 들어 전자 상거래 거래에서 지불이 제한 시간 내에 완료되지 않으면 주문이 닫히는 시나리오가 있습니다. 이 경우 주문이 생성될 때 지연 메시지가 전송됩니다. 이 메시지는 소비자에게 30분 후에 전달되며, 소비자는 해당 주문이 지불되었는지 확인해야 합니다. 지불이 완료되지 않으면 주문이 닫히고, 지불이 완료되면 메시지는 무시됩니다.
  • 메시지에 의해 트리거된 지연 작업이 있는 시나리오. 예를 들어 특정 시간이 지난 후에 사용자에게 알림 메시지를 보내는 경우.

데드레터 익스체인지 + 메시지 TTL 방식

이 방법의 핵심 아이디어는 소비자가 없는 큐를 생성하고 메시지 만료 시간(TTL)을 활용하는 것입니다. 메시지가 만료되면 데드레터가 되어 데드레터 익스체인지를 통해 데드레터 큐로 라우팅되어 소비될 수 있습니다.

이 방법에서 메시지 만료 시간은 메시지 지연 시간으로 사용됩니다. 예를 들어, 메시지 TTL을 30초로 설정하고 큐에 대한 소비자가 없는 경우, 메시지는 30초 후에 만료되어 데드레터가 되며, 데드레터 큐에서 처리됩니다.

이 방법을 구현하려면 아래 튜토리얼에 설명된 대로 속성을 설정해야 합니다:

지연 메시지 플러그인 솔루션

1. 플러그인 설치

rabbitmq-delayed-message-exchange GitHub 저장소:

https://github.com/rabbitmq/rabbitmq-delayed-message-exchange/releases

GitHub 릴리스 페이지의 assets 섹션에서 rabbitmq_delayed_message_exchange-3.8.9-0199d11c.ez 파일을 다운로드하고 RabbitMQ 플러그인 디렉터리(plugins 디렉터리)에 파일을 배치합니다.

참고: 버전 번호는 이 튜토리얼의 것과 다를 수 있습니다. RabbitMQ가 최신 버전인 경우, 플러그인의 최신 버전을 선택하면 됩니다.

2. 플러그인 활성화

rabbitmq-plugins enable rabbitmq_delayed_message_exchange

3. 익스체인지 정의

지연 메시지를 보낼 수 있도록 x-delayed-type을 사용하여 사용자 정의 익스체인지 속성을 설정합니다.

props := make(map[string]interface{})
// 지연 메시지를 보낼 수 있도록 Key 매개변수 설정
props["x-delayed-type"] = "direct"

// 익스체인지 정의
err = ch.ExchangeDeclare(
"delay.queue", // 익스체인지 이름
"fanout",      // 익스체인지 타입
true,          // Durability
false,
false,
false,
props,         // 속성 설정
)

4. 지연 메시지 전송

메시지 헤더(x-delay)를 사용하여 메시지 지연 시간을 설정합니다.

msgHeaders := make(map[string]interface{})
// 메시지 헤더를 사용하여 메시지 지연 시간을 밀리초 단위로 설정
msgHeaders["x-delay"] = 6000

err = ch.Publish(
"delay.queue", // 익스체인지 이름
"",            // 라우팅 매개변수
false,
false,
amqp.Publishing{
Headers: msgHeaders,   // 메시지 헤더 설정
ContentType: "text/plain",
Body: []byte(body),
})

참고: Alibaba Cloud의 RabbitMQ Message Queue 서비스를 직접 사용하는 경우 플러그인을 설치하지 않고 메시지 헤더 속성(delay)을 사용하여 지연 시간을 설정할 수 있습니다. Alibaba Cloud는 이미 이 목적으로 RabbitMQ를 확장했습니다.