This article introduces RabbitMQ’s dead letter queue and delay queue.
This is also a common question in Java backend interviews.
Dead-letter queue
Introduction to the
DLX, which stands for dead-letter-exchange, can be called a dead-letter Exchange or a dead-letter mailbox. When a message becomes dead message in one queue, it can be re-sent to another exchange, the DLX. Queues bound to DLX are called dead letter queues.
There are several things that can cause messages to become dead-letter:
The message is rejected (basic. Reject/ basic. Nack) and the Requeue parameter is set to false;
Message expiration;
The queue length reaches the maximum. Procedure
The DLX is a normal switch, no different from a normal switch, and it can be specified on any queue, in effect setting the attributes of a queue. When there is a dead letter in the queue, RabbitMQ will automatically re-publish the message to the set DLX and route it to another queue, the dead letter queue. Messages in this queue can be listened to for processing. This feature, combined with setting the TTL of messages to 0, compensates for the immediate parameter.
Methods to add DLX to queues
Method 1: code method
// Create DLX: dlx_exchange channel.exchangeDeclare(“dlx_exchange”, “direct”); Map<String, Object> args = new HashMap<String, Object>; args.put(“x-dead-letter-exchange”, “dlx_exchange”); QueueDeclare (“myqueue”, false, false, false, args); // Add DLX channel.queueDeclare(“myqueue”, false, false, args); You can also specify routing keys for the DLX. (If not specified, the routing key of the original queue is used.)
args.put(“x-dead-letter-routing-key”,”dlx-routing-key”); Method 2: Command mode
Rabbitmqctl set_policy queues.*” ‘{“dead-letter-exchange”:”dlx_exchange”}’ –apply-to queues example code
channel.exchangeDeclare(“exchange.dlx”, “direct”, true); channel.exchangeDeclare(“exchange.normal”, “fanout”, true); Map<String, Object> args = new HashMap<String, Object>(); args.put(“x-message-ttl”, 10000); args.put(“x-dead-letter-exchange” , “exchange.dlx”); args.put(“x-dead-letter-routing-key” , “routingkey”); channel.queueDeclare(“queue.normal” , true, false, false, args); channel.queueBind(“queue.normal”, “exchange.normal”, “”); channel.queueDeclare(“queue.dlx”, true, false, false, null); channel.queueBind(“queue.dlx”, “exchange.dlx” , “routingkey”); channel.basicPublish(“exchange.normal” , “rk”, MessageProperties.PERSISTENT_TEXT_PLAIN, “dlx”.getBytes());
Exchange. Normal and exchange. DLX are created, and two queues queue.
Web management page results
As shown in the following figure (Figure 1-1), both queues are marked with “D”, the abbreviation of durable, that is, queues are durable. Queue. Normal Is also configured with TTL, DLX, and DLK, where DLX refers to the x-dead-letter-routing-key attribute.
Case analysis
As shown in the following figure (Figure 1-2), the producer first sends a message with the routing key “Rk”, which is then successfully stored in queue. Normal through the exchange. Since queue. Normal has an expiration time of 10 seconds, within which no consumers consume the message, the message is considered expired. DLX is set, and when the message expires, it is dropped to the exchange. DLX. The queue that matches the exchange is found.
DLX is a very useful feature for RabbitMQ. It can handle exceptions where a message is placed in a dead letter queue because it is not properly consumed by a consumer (basic. Nack or basic. Reject). Subsequent analysts can consume the contents of the dead letter queue to analyze the exceptions encountered at the time, thereby improving and optimizing the system. DLX can also be used with TTL to implement delayed queuing, as detailed in the next section.
Delays in the queue
Introduction to the
Delay queues are used to store delayed messages. Delayed message: When a message is sent, the consumer does not want to receive the message immediately, but waits a certain amount of time before the consumer can receive the message for consumption. Big data Training
RabbitMQ does not support delay queuing directly in THE AMQP protocol or RabbitMQ itself, but there are two ways to implement it indirectly:
Scheme 1: Use rabbitmq-delayed-message-exchange plug-in. (RabbitMQ 3.6.x is available)
Scheme 2: Use DLX and TTL described earlier to simulate the function of delay queuing.
Figure 1-2 shows not only the use of the dead letter queue, but also the use of the delay queue. For queue.dlx, the dead letter queue, it can also be regarded as a delay queue. Suppose an application needs to set a 10-second delay for each message, and the producer stores the messages sent through the exchange. Normal queue. The consumer does not subscribe to queue. Normal, but to queue. DLX. When messages expire from queue. Normal and are stored in queue. DLX, the consumer happens to consume the message with a delay of 10 seconds.
In real applications, the delay queue can be divided into multiple levels according to the length of the delay, generally divided into 5 seconds, 10 seconds, 30 seconds, 1 minute, 5 minutes, 10 minutes, 30 minutes, and 1 hour. Of course, you can also specify the level.
The following figure (Figure 2-1) is an example. For simplicity, just set the four levels of 5 seconds, 10 seconds, 30 seconds, and 1 minute. According to different requirements, the producer sends messages to different queues bound to the switch by setting different routing keys. In this case, DLX and the corresponding dead-letter queue are configured respectively. When the corresponding messages expire, they are transferred to the corresponding dead-letter queue (delay queue). In this way, consumers can choose delay queues with different delay levels for consumption according to the service conditions.
Usage scenarios
Deferred queuing can be used in many different scenarios, such as:
Scenario where the user places an order: The user has 30 minutes to pay after placing an order. If the payment is not made within 30 minutes, the order will be cancelled. Solution: After the user places the order, the cancellation message is sent to the delay queue, and the delay time is set to 30 minutes. The subscriber program receives the cancellation message 30 minutes later and determines whether the order status is paid or not. If not, the order status is set to cancelled. Timing remote control scenario: The user wants to remotely control the smart device at home at a specified time by using a mobile phone.
Solution: Suppose the user wants to turn on the water heater. First, the message to turn on the water heater is sent to the delay queue, and the delay time is set to the difference between the user’s desired time and the present time. The subscriber program that turns on the water heater receives the message at a specified time and pushes the command to the smart device.
Note that delayed queued messages cannot be cancelled. The solution is to determine the current state of the business corresponding to the message when consuming the message. For example: for the order cancellation, when receiving the message, read the corresponding database information of the message, if the state is already paid, no operation, if the state is not paid, then changed to cancelled.