RabbitMQ(4) RabbitMQ 사서함(DLX)

3744 단어 rabbitmqTTLdlx
DLX, Dead-Letter-Exchange(사용 사서함)
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를 배우기 위해 생각한 것입니다. 실제 응용에서 다른 대체 방안이 있을 수 있으니 공부하는 셈입니다.

좋은 웹페이지 즐겨찾기