In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
Whether the messages in Java RabbitMQ will be out of date if they are not consumed for a long time, this article introduces the corresponding analysis and solutions in detail, hoping to help more partners who want to solve this problem to find a more simple and feasible way.
1. Default
First of all, let's look at the default.
By default, messages do not expire, that is, when messages are sent on weekdays, if we do not set any parameters related to message expiration, the messages will not expire, and even if the messages are not consumed, they will always be stored in the queue.
There is no need for me to demonstrate the specific code in this case. Brother Song's previous articles are basically like this when it comes to RabbitMQ.
2. TTL
TTL (Time-To-Live), the time the message lives, that is, the validity period of the message. If we want the message to have a lifetime, we can achieve this requirement by setting up TTL. If the survival time of the message exceeds the TTL and has not been sent, the message will become a dead letter. Brother Song will introduce you later about the dead letter and the dead letter queue.
There are two different ways to set up TTL:
When declaring a queue, we can set the validity period of the message in the queue properties so that all messages entering the queue have the same validity period.
Set the validity period of the message when sending the message, so that different messages have different validity periods.
What if both are set?
Whichever is short.
When we set the validity period of the message, the message will be deleted from the queue when it expires (enter the dead letter queue, as later, it will no longer be marked), but there are some differences in the timing of deletion between the two methods:
For the first method, when the message queue sets the expiration time, the message will be deleted when it expires, because there is a message queue after the message enters the RabbitMQ, and the header of the queue is the earliest message to expire, so RabbitMQ only needs a scheduled task to scan for expired messages from the header, and delete them directly if any. For the second method, the message will not be deleted immediately after it expires, but will only be deleted when it is delivered to the consumer, because in the second way, the expiration time of each message is different, and you want to know which message expires. You have to traverse all the messages in the queue to achieve this, which is more performance-consuming when there are more messages, so for the second way, Delete the message only when it is delivered to the consumer.
After introducing TTL, let's take a look at the specific usage.
All the next code Songge takes the AMPQ packaged in Spring Boot as an example to explain.
2.1 single message expires
Let's first look at the expiration time of a single message.
First create a Spring Boot project and introduce Web and RabbitMQ dependencies, as follows:
Then configure the connection information of RabbitMQ in application.properties, as follows:
Spring.rabbitmq.host=127.0.0.1
Spring.rabbitmq.port=5672
Spring.rabbitmq.username=guest
Spring.rabbitmq.password=guest
Spring.rabbitmq.virtual-host=/
Next, configure the message queue a little bit:
@ Configurationpublic class QueueConfig {public static final String JAVABOY_QUEUE_DEMO = "javaboy_queue_demo"; public static final String JAVABOY_EXCHANGE_DEMO = "javaboy_exchange_demo"; public static final String HELLO_ROUTING_KEY = "hello_routing_key"; @ Bean Queue queue () {return new Queue (JAVABOY_QUEUE_DEMO, true, false, false);} @ Bean DirectExchange directExchange () {return new DirectExchange (JAVABOY_EXCHANGE_DEMO, true, false) } @ Bean Binding binding () {return BindingBuilder.bind (queue ()) .to (directExchange ()) .with (HELLO_ROUTING_KEY);}}
This configuration class mainly does three things: configure the message queue, configure the switch, and bind the two together.
First, configure a message queue, new a Queue: the first parameter is the name of the message queue; the second parameter indicates whether the message is persistent; the third parameter indicates whether the message queue is exclusive, which is generally set to false, that is, not exclusive; the fourth parameter indicates that if the queue does not have any subscribing consumers, the queue will be automatically deleted, generally applicable to temporary queues.
Configure a DirectExchange switch.
Bind the switch to the queue.
This configuration should be very simple, there is nothing to explain, there is an exclusiveness, Brother Song says a little more here:
With regard to exclusivity, if set to true, the message queue can only be accessed by the Connection that created it, and no other Connection can access the message queue. If you try to redeclare or access the exclusive queue in a different connection, the system will report an error that the resource is locked. On the other hand, for an exclusive queue, the message queue is also automatically deleted when the connection is disconnected (whether or not the queue is declared to be persistent).
Next, a message sending interface is provided, as follows:
@ RestControllerpublic class HelloController {@ Autowired RabbitTemplate rabbitTemplate; @ GetMapping ("/ hello") public void hello () {Message message = MessageBuilder.withBody ("hello javaboy" .getBytes ()) .setExpiration ("10000") .build (); rabbitTemplate.convertAndSend (QueueConfig.JAVABOY_QUEUE_DEMO, message);}}
We can set the expiration time of the message when creating the Message object. Here, set the expiration time of the message to 10 seconds.
That's it!
Next, we start the project and conduct a message delivery test. When the message is sent successfully, because there is no consumer, the message will not be consumed. Open the RabbitMQ management page and click on the Queues tab. After 10s, we will find that the message has disappeared:
It's easy!
To set the expiration time of a single message is to set the validity period of the message when the message is sent.
2.2 queue message expiration
Set the message expiration time for the queue as follows:
BeanQueue queue () {Map args = new HashMap (); args.put ("x-message-ttl", 10000); return new Queue (JAVABOY_QUEUE_DEMO, true, false, false, args);}
After the setting is completed, we modify the sending logic of the message, as follows:
@ RestControllerpublic class HelloController {@ Autowired RabbitTemplate rabbitTemplate; @ GetMapping ("/ hello") public void hello () {Message message = MessageBuilder.withBody ("hello javaboy" .getBytes ()) .build (); rabbitTemplate.convertAndSend (QueueConfig.JAVABOY_QUEUE_DEMO, message);}}
As you can see, the message can be sent normally without setting the expiration time of the message.
OK, start the project and send a message for testing. View the RabbitMQ management page as follows:
As you can see, the Features attributes D and TTL,D of the message queue indicate that the message in the message queue is persisted, and TTL indicates that the message will expire.
Refresh the page after 10 seconds and find that the number of messages has returned to 0.
This is to set the message expiration time for the message queue, once set, all messages entering the queue have an expiration time.
2.3 Special circumstances
In another special case, the expiration time TTL of the message is set to 0, which means that if the message cannot be consumed immediately, it will be discarded immediately. This feature can partially replace the immediate parameter previously supported by RabbitMQ3.0, partly because the basic.return method returns the message body when the immediate parameter fails to be delivered (this function can be realized by using the dead letter queue).
The specific code Songge will not demonstrate, this should be relatively easy.
3. Dead letter queue
Some friends can't help but ask, where is the deleted message? Has it really been deleted? No, no, no! This involves the dead letter queue, let's take a look at the dead letter queue.
3.1 Dead letter switch
Dead letter switch, Dead-Letter-Exchange is DLX.
Dead-letter switches are used to receive dead-letter messages (Dead Message), so what is dead-letter messages? There are several situations in which a general message becomes a dead letter message:
Message is rejected (Basic.Reject/Basic.Nack), and the requeue parameter is set to false
Message expires
The queue reaches the maximum length
When a message becomes a dead-letter message in a queue, it is sent to DLX, and the message queue bound to DLX is called a dead-letter queue.
DLX is essentially an ordinary switch. We can specify DLX for any queue. When there is a dead letter in the queue, RabbitMQ will automatically publish the dead message to DLX and be routed to another queue bound with DLX (that is, dead letter queue).
3.2 Dead letter queue
It is easy to understand that the queue bound to the dead-letter switch is the dead-letter queue.
3.3 practice
Let's look at a simple example.
First let's create a dead-letter switch, then create a dead-letter queue, and then bind the dead-letter switch to the dead-letter queue:
Public static final String DLX_EXCHANGE_NAME = "dlx_exchange_name"; public static final String DLX_QUEUE_NAME = "dlx_queue_name"; public static final String DLX_ROUTING_KEY = "dlx_routing_key"; / * configure dead-letter switch * * @ return * / @ BeanDirectExchange dlxDirectExchange () {return new DirectExchange (DLX_EXCHANGE_NAME, true, false) } / * configure the dead letter queue * @ return * / @ BeanQueue dlxQueue () {return new Queue (DLX_QUEUE_NAME);} / * bind the dead letter queue and the dead letter switch * @ return * / @ BeanBinding dlxBinding () {return BindingBuilder.bind (dlxQueue ()) .to (dlxDirectExchange ()) .with (DLX_ROUTING_KEY);}
In fact, this is no different from an ordinary switch, an ordinary message queue.
Next, configure a dead-letter switch for message queuing, as follows:
@ BeanQueue queue () {Map args = new HashMap (); / / set message expiration time args.put ("x-message-ttl", 0); / / set dead-letter switch args.put ("x-dead-letter-exchange", DLX_EXCHANGE_NAME); / / set dead-letter routing_key args.put ("x-dead-letter-routing-key", DLX_ROUTING_KEY) Return new Queue (JAVABOY_QUEUE_DEMO, true, false, false, args);}
Just two parameters:
X-dead-letter-exchange: configure a dead-letter switch.
X-dead-letter-routing-key: configure dead letter routing_key.
This is set up.
Messages sent to this message queue in the future will be sent to DLX if problems such as nack, reject, or expiration occur, and then go to the message queue bound to DLX.
The consumption of dead letter message queues is no different from that of ordinary message queues:
@ RabbitListener (queues = QueueConfig.DLX_QUEUE_NAME) public void dlxHandle (String msg) {System.out.println ("dlx msg =" + msg);}
It's easy, right?
This is the answer to the question about whether the message in Java RabbitMQ will be out of date if it is not consumed for a long time. I hope the above content can be of some help to you. If you still have a lot of doubts to be solved, you can follow the industry information channel for more related knowledge.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.