RabbitMQ(4) RabbitMQ 사서함(DLX)
DLX를 이용하면 메시지가 한 대기열에서 사신이 되면 다른 Exchange로 다시 퍼블릭됩니다. 이 Exchange가 DLX입니다.소식이 사신으로 바뀌는 데는 줄곧 다음과 같은 몇 가지 상황이 있다.
메시지가 거부되었습니다. (basic.reject or basic.nack) 그리고requeue=false
메시지 TTL이 만료되었습니다
대기열이 최대 길이에 도달합니다
DLX도 정상적인 Exchange는 일반적인 Exchange와 다를 것이 없다. 어떤 대기열에서 지정될 수 있고 실제로는 특정한 대기열의 속성을 설정한다. 이 대기열에 죽은 편지가 있을 때 RabbitMQ는 자동으로 이 메시지를 설정된 Exchange에 다시 발표하고 다른 대기열로 이동한다.publish는 이 대기열의 메시지를 감청하여 해당하는 처리를 할 수 있다.이 기능은 RabbitMQ 3.0.0이 이전에 지원한immediate 매개 변수에서publish에 확인하는 기능을 보완할 수 있습니다.
JAVA의 SDK 설정
channel.exchangeDeclare("some.exchange.name", "direct"); Map<String, Object> args = new HashMap<String, Object>(); args.put("x-dead-letter-exchange", "some.exchange.name"); channel.queueDeclare("myqueue", false, false, false, args);
이 DLX에 routing key를 지정할 수도 있습니다. 특별한 지정이 없으면 원래 대기열의 routing key를 사용합니다.
args.put("x-dead-letter-routing-key", "some-routing-key");
정책을 사용하여 구성할 수도 있습니다.
rabbitmqctl set_policy DLX ".*" '{"dead-letter-exchange":"my-dlx"}' --apply-to queues
'죽은 편지'가 리퍼블릭될 때, 메시지의 헤더에'x-death'라는 그룹 내용을 추가합니다. 다음 필드를 포함합니다.
queue - the name of the queue the message was in before it was dead-lettered,
reason - see below,
time - the date and time the message was dead lettered as a 64-bit AMQP format timestamp,
exchange - the exchange the message was published to (note that this will be a dead letter exchange if the message is dead lettered multiple times), and
routing-keys - the routing keys (including CC keys but excluding BCC ones) the message was published with.
original-expiration (if the message was dead-letterered due to per-message TTL) - the originalexpiration property of the message. The expiration property is removed from the message on dead-lettering in order to prevent it from expiring again in any queues it is routed to.
The reason is a name describing why the message was dead-lettered and is one of the following:
rejected - the message was rejected with requeue=false,
expired - the TTL of the message expired; or
maxlen - the maximum allowed queue length was exceeded.
immediate 파라미터를 사용할 때 소비자가 메시지를 거절하면 이 응답은publish에 통지할 수 없지만 DLX를 이용하면 거절 메시지는'사신'으로 변한다. 이 사신은 Republish에서 DLX 루트의 대기열로 이동한다. 이 새로운 정보의 헤더에 있는 x-death 내용을 분석하면 메시지가 사신이 된 원인을 판단할 수 있어publish 측에서 더욱 유연하게 처리할 수 있다.
TTL과 DLX를 결합하여 사용하는 장면
만약에 제가 이런 응용 장면이 필요하다면consumer는 무조건 종료할 수 있습니다. 종료한 후에 감청한 대기열도 함께 삭제하기를 바랍니다. 그러나 대기열에 메시지가 있으면 DLX 대기열로 전송할 수 있도록 요구합니다.
만약queue의 AUTO_로DELETE 기능은 consumer가 종료되면 대기열에 메시지가 있든 없든 대기열이 삭제됩니다. 이 방법은 안 됩니다.
우리는 이렇게 융통성 있게 실현할 수 있다.
1. 대기열의 "x-expires"매개 변수를 300S로 합니다. 즉, 대기열은 소비자가 300S를 비우지 않으면 자동으로 삭제됩니다)
2. 대기열의 "x-message-ttl"매개 변수를 30S로 합니다. 즉, 메시지는 30S만 살아남습니다.
3. 생산자publish 메시지를 만들 때immediate 속성을 설정한다. 즉publish를 요구할 때 반드시 소비자가 존재한다는 것이다.
이렇게 생산자는 끊임없이 메시지를 대기열에 넣는 데 성공했다.publish시 immediate 속성을 판단했기 때문에,publish 메시지를 판단할 때 소비자는 반드시 존재한다. 만약에 소비자가 제때에 처리하지 않아 메시지가 쌓이고 30S내에 처리되지 않으면 이 메시지들은 Republish에서 DLX 루트의 대기열에 저장된다. 설령 이때 소비자가 이상하게 퇴장하더라도 상관없다.대기열은 적어도 300S 이후에야 자동으로 삭제되기 때문에, 모든 소비를 DLX 대기열로 리퍼블릭하는 데 충분한 시간이 있다
이 응용 장면은 제가 제멋대로 생각한 것입니다. 순전히 Rabbit MQ를 배우기 위해 생각한 것입니다. 실제 응용에서 다른 대체 방안이 있을 수 있으니 공부하는 셈입니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
RabbitMQ를 사용하여 다음 주차장 시뮬레이션을 비동기식으로 만들려면 어떻게 해야 합니까?Java의 동시성에 대한 다양한 접근 방식을 배우고 이해하려고 합니다. 저는 주차장 시뮬레이션의 직렬화된 구현을 가지고 있습니다. 프로그램이 대신 Rabbitmq를 사용하도록 만들고 싶습니다. 어떻게 해야 합니까? ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.