In the actual business we will meet the information produced by the producers, not immediately consume, but delay a period of time in consumption. The RABBITMQ itself does not directly support the delay queue feature, but we can implement the delay queue based on its characteristics Per-queue Message TTL and Dead letter exchanges . You can also set the priority of messages by changing the properties . 1.per-queue Message TTL
The RABBITMQ can set the TTL (Expiration time) for messages and queues. There are two ways to set the message expiration time in a queue, which can be used in the Times to Live, TTL.
The first approach is through the Queue property setting, where all messages in the queue have the same expiration time.
The second method is to set the message separately, each message TTL can be different . If both methods are used at the same time, the message expires with a value that is less than the TTL between the two. Once the message has exceeded the set TTL value in the queue's lifetime, it becomes a dead message and the consumer will no longer receive the message. 2.Dead Letter Exchanges
When a message becomes dead-letter in one queue, it can be re-publish to another exchange. The message becomes dead letter always has the following situation: The message is rejected (Basic.reject or basic.nack) and the Requeue=false message TTL expiration queue reaches the maximum length
is actually set the properties of a queue, when there is dead letter in this queue, RABBITMQ will automatically republish this message to the set of exchange, and then be routed to another queue, publish can listen to the message in this queue to do the corresponding processing, This feature can compensate for the ability to confirm to publish in the immediate parameters previously supported by RABBITMQ 3.0.0. One, set the TTL on the queue
1. Establish Delay.exchange
Here internal is set to No, otherwise it will not be accepted dead Letter,yes means that Exchange cannot be used by the client to push messages and is used only for binding between Exchange and exchange. 2. Set up delay queue
Configure the delay 5min queue (x-message-ttl=300000) as above
X-max-length: The maximum backlog of messages can be set according to their actual situation, exceeding the limit messages will not be lost, will immediately turn to Delay.exchange for delivery
X-dead-letter-exchange: Set to a delay.exchange that has just been configured and will be posted via delay.exchange after the message expires
There is no need to configure "Dead letter routing Key" to overwrite the routingkey that is carried when the message is sent, resulting in the inability to route back to the Delay.exchange 3 that was just configured . Configuring the delay Routing rule
Messages that require delay are routed to the specified delay queue after exchange
1) Create Delaysync.exchange to route messages to the delay queue via routing key
2) Configure Delay.exchange to post messages to the normal consumption queue
Configuration is complete.
Let's test it with code:
Producers:
Package cn.slimsmart.study.rabbitmq.delayqueue.queue;
Import java.io.IOException;
Import Com.rabbitmq.client.Channel;
Import com.rabbitmq.client.Connection;
Import Com.rabbitmq.client.ConnectionFactory;
public class Producer {private static String queue_name = "Test.queue"; public static void Main (string[] args) throws IOException {ConnectionFactory factory = new Connectionfactor
Y ();
Factory.sethost ("10.1.199.169");
Factory.setusername ("admin");
Factory.setpassword ("123456");
Connection Connection = Factory.newconnection ();
Channel channel = Connection.createchannel ();
Declaration Queue Channel.queuedeclare (Queue_name, True, False, false, NULL);
String message = "Hello world!" + system.currenttimemillis ();
Channel.basicpublish ("Delaysync.exchange", "deal.message", NULL, Message.getbytes ()); SYSTEM.OUT.PRINTLN ("Sent message:" + message + ", Date:" + System.currenttimemillis ());
Close the channel and connect the Channel.close ();
Connection.close (); }
}
Consumer:
Package cn.slimsmart.study.rabbitmq.delayqueue.queue;
Import Com.rabbitmq.client.Channel;
Import com.rabbitmq.client.Connection;
Import Com.rabbitmq.client.ConnectionFactory;
Import Com.rabbitmq.client.QueueingConsumer;
public class Consumer {private static String queue_name = "Test.queue"; public static void Main (string[] args) throws Exception {ConnectionFactory factory = new ConnectionFactory (
);
Factory.sethost ("10.1.199.169");
Factory.setusername ("admin");
Factory.setpassword ("123456");
Connection Connection = Factory.newconnection ();
Channel channel = Connection.createchannel ();
Declaration Queue Channel.queuedeclare (Queue_name, True, False, false, NULL);
Queueingconsumer consumer = new Queueingconsumer (channel);
Specifies the consumption queue Channel.basicconsume (Queue_name, true, consumer); while (true) {///Nextdelivery is a blocking method (the internal implementation is actually a take method for blocking the queue) Queueingconsumer.deliv
ery delivery = Consumer.nextdelivery ();
String message = new String (Delivery.getbody ());
System.out.println ("received message:" + message + ", Date:" + System.currenttimemillis ()); }
}
}
Second, set the TTL on the message
Implementation code:
Producers:
Package cn.slimsmart.study.rabbitmq.delayqueue.message;
Import java.io.IOException;
Import Java.util.HashMap;
Import Com.rabbitmq.client.AMQP;
Import Com.rabbitmq.client.Channel;
Import com.rabbitmq.client.Connection;
Import Com.rabbitmq.client.ConnectionFactory;
public class Producer {private static String queue_name = "Message_ttl_queue";
public static void Main (string[] args) throws IOException {ConnectionFactory factory = new ConnectionFactory ();
Factory.sethost ("10.1.199.169");
Factory.setusername ("admin");
Factory.setpassword ("123456");
Connection Connection = Factory.newconnection ();
Channel channel = Connection.createchannel ();
hashmap<string, object> arguments = new hashmap<string, object> ();
Arguments.put ("X-dead-letter-exchange", "Amq.direct");
Arguments.put ("X-dead-letter-routing-key", "Message_ttl_routingkey"); Channel.queuedeclare ("Delay_queue", True, False, false, arguments);
Declaration Queue Channel.queuedeclare (Queue_name, True, False, false, NULL);
Bind Route Channel.queuebind (queue_name, "Amq.direct", "Message_ttl_routingkey");
String message = "Hello world!" + system.currenttimemillis (); Set the Delay property for AMQP. Basicproperties.builder Builder = new AMQP.
Basicproperties.builder (); Persistent non-persistent (1) or persistent (2) AMQP.
Basicproperties properties = builder.expiration ("300000"). DeliveryMode (2). build ();
Routingkey =delay_queue for forwarding Channel.basicpublish ("", "Delay_queue", Properties, Message.getbytes ());
SYSTEM.OUT.PRINTLN ("Sent message:" + message + ", Date:" + System.currenttimemillis ());
Close the channel and connect the Channel.close ();
Connection.close ();
}
}
Consumer:
Package cn.slimsmart.study.rabbitmq.delayqueue.message;
Import Java.util.HashMap;
Import Com.rabbitmq.client.Channel;
Import com.rabbitmq.client.Connection;
Import Com.rabbitmq.client.ConnectionFactory;
Import Com.rabbitmq.client.QueueingConsumer;
public class Consumer {private static String queue_name = "Message_ttl_queue"; public static void Main (string[] args) throws Exception {ConnectionFactory factory = new ConnectionFactory (
);
Factory.sethost ("10.1.199.169");
Factory.setusername ("admin");
Factory.setpassword ("123456");
Connection Connection = Factory.newconnection ();
Channel channel = Connection.createchannel ();
hashmap<string, object> arguments = new hashmap<string, object> ();
Arguments.put ("X-dead-letter-exchange", "Amq.direct"); Arguments.put ("X-dead-letter-routing-key", "mesSage_ttl_routingkey ");
Channel.queuedeclare ("Delay_queue", True, False, false, arguments);
Declaration Queue Channel.queuedeclare (Queue_name, True, False, false, NULL);
Bind Route Channel.queuebind (queue_name, "Amq.direct", "Message_ttl_routingkey");
Queueingconsumer consumer = new Queueingconsumer (channel);
Specifies the consumption queue Channel.basicconsume (Queue_name, true, consumer); while (true) {///Nextdelivery is a blocking method (the internal implementation is actually a take method for blocking the queue) Queueingconsumer.delivery de
livery = Consumer.nextdelivery ();
String message = new String (Delivery.getbody ());
System.out.println ("received message:" + message + ", Date:" + System.currenttimemillis ()); }
}
}