preface
RabbitMQ introduction: RabbitMQ is a message oriented middleware based on AMQP standard and Erlang language.
Tip: the following is the main content of this article
1, RabbitMQ infrastructure
- Producer: as the generator of the message.
- Consumer: the consumer of the message.
- Connection: the TCP connection between the message publisher or message consumer and the broker.
- Channel: a channel is a logical connection established within a connection. If the application supports multithreading, a separate channel is usually created for each thread to communicate. The AMQP method includes a channel id to help the client and message broker identify the channel. Therefore, the channels are completely isolated, reducing the overhead of the operating system for establishing TCP connection.
- Broker: an application that receives and distributes messages. RabbitMQ service is Message Broker.
- Virtual host: virtual machine, designed for multi tenant and security factors, divides the basic components of AMQP into a virtual group. It can be compared with mysql database, which will create many libraries, and the libraries are independent. When multiple different users use the services provided by the same RabbitMQserver, they can be divided into multiple vhosts. Each user creates an exchange / queue in its own vhost.
- Queue: queue, message queue, which receives messages and caches messages. Messages are finally sent here to wait for consumer s to take them away.
- Binding: binding, virtual connection between exchange and queue. Binding can contain routing key. The binding information is saved in the query table in exchange for the distribution basis of message s
- Exchange: the switch. The message arrives at the first stop of the broker, matches the routing key in the query table according to the distribution rules, and distributes the message to the queue.
Common types of switches are:
Fanout: broadcast and deliver messages to all queues bound to the switch
Direct: direct, which sends messages to queues that match the specified routing key
Topic: wildcard, which gives the message to the queue conforming to the routing pattern
2, Working mode
1, Theory of six working modes
RabbitMQ Six working modes are provided, including simple mode work queues,Publish/Subscribe Publish and subscribe mode Routing Routing mode Topics Theme mode RPC Remote call mode (remote call, not message queue)
Simple mode: a producer sends the production message to the queue, and a consumer takes the message from the queue to consume the message. One producer and one consumer do not need to set the switch (use the default switch)
Note: similar to a mailbox, messages can be cached; The producer delivers the message to it, and the consumer takes the message out of it.
Work queues mode: a producer sends production messages to the queue, and one or more consumers take messages from the queue to consume messages. One producer and multiple consumers (competitive relationship) do not need to set the switch (use the default switch)
Note: when the task is too heavy or there are many tasks, using work queue can improve the speed of task processing. Application scenario: during the Chinese New Year holiday, 12306 grabs tickets and sends text messages to users. You can access multiple SMS services for sending, providing task processing speed.
Pub/Sub subscription mode: a producer sends a message to the switch, which processes the message. The queue is arbitrarily bound to the switch, assigns the message to a queue, and one or more consumers take the message from the queue to consume the message. You need to set the switch of type fanout and bind the switch to the queue. After sending a message to the switch, the exchange opportunity sends the message to the bound queue.
Note: Exchange (switch) is only responsible for forwarding messages and does not have the ability to store messages. Therefore, if there is no queue bound to exchange or no queue that meets the routing rules, the messages will be lost!
Routing mode: a producer sends production messages to the switch and specifies a routing key. The queue is bound to the switch through the routing key. When consuming, consumers need to take messages from the switch according to the routing key to consume messages. You need to set the switch with the type of direct, bind the switch to the queue, and specify the routing key. When a message is sent to the switch, the switch will send the message to the corresponding queue according to the routing key.
Note: the Routing mode requires the queue to specify the routing key when binding the switch, and the message will be forwarded to the queue matching the routing key.
Topics wildcard mode: a producer sends messages to the switch and uses wildcards (similar to the fuzzy query in mysql, for example, to obtain a batch of data with item prefix). The binding between the queue and the switch is through wildcards. When consuming, consumers need to get messages from the switch according to the wildcards, Carry out consumption messages. It is necessary to set the switch with the type of topic, bind the switch to the queue, and specify the routing key in the wildcard mode. When a message is sent to the switch, the switch will send the message to the corresponding queue according to the routing key
Description: wildcard rule: # match one or more words, * match exactly one word. For example, Lazy. # can match Lazy.insert.content or Lazy.insert, and Lazy. * can only match Lazy.insert.
2, Codes for 6 operating modes
1, Demo demonstration of 6 working modes
Create a Maven project and introduce pom dependency:
<dependencies> <!--rabbitmq client--> <dependency> <groupId>com.rabbitmq</groupId> <artifactId>amqp-client</artifactId> <version>5.3.0</version> </dependency> <!--json Conversion kit--> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.5</version> </dependency> </dependencies>
Create a tool class connecting Rabbitmq:
import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; public class RabbitUtils { private static ConnectionFactory connectionFactory = new ConnectionFactory(); static { connectionFactory.setHost("Yours rabbitmq of ip address"); connectionFactory.setPort(5672);//The default port number of RabbitMQ, which can be modified according to the actual situation connectionFactory.setUsername("Yours rabbitmq User name for"); connectionFactory.setPassword("Yours rabbitmq User password for"); connectionFactory.setVirtualHost("Yours rabbitmq Virtual machine for"); } public static Connection getConnection(){ Connection conn = null; try { conn = connectionFactory.newConnection(); return conn; } catch (Exception e) { throw new RuntimeException(e); } } }
Simple mode:
In order to distinguish and understand, I create a virtual machine for each mode. Here, I go to the rabbitMq control page to create a virtual machine
Modify the virtual machine of the tool class:
producer:
import com.liao.rabbitmq.utils.RabbitConstant; import com.liao.rabbitmq.utils.RabbitUtils; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; public class Producer { public static void main(String[] args) throws Exception { //Get TCP long connection Connection conn = RabbitUtils.getConnection(); //Create a communication "channel", which is equivalent to a virtual connection in TCP Channel channel = conn.createChannel(); //Create a queue, declare and create a queue, and use it if it already exists //Five parameters of channel.queueDeclare //First parameter: queue name ID //The second parameter: whether to persist. false corresponds to non persistent data. If MQ stops, the data will be lost //The third parameter: whether to privatize the queue. false means that all consumers can access it. true means that only consumers who own it for the first time can always use it. Other consumers are not allowed to access it //Fourth: whether to delete automatically. false means that the queue will not be deleted automatically after the connection is stopped //Other additional parameters, null channel.queueDeclare(RabbitConstant.QUEUE_TEST,false, false, false, null); String message = "To send message"; //Four parameters of channel.basicPublish //The exchange switch is temporarily unavailable and will only be used later when publishing and subscribing //Queue name //Additional settings properties //The last parameter is an array of message bytes to pass channel.basicPublish("", RabbitConstant.QUEUE_TEST, null,message.getBytes()); channel.close(); conn.close(); System.out.println("===Sent successfully==="); } }
consumer:
import com.liao.rabbitmq.utils.RabbitConstant; import com.liao.rabbitmq.utils.RabbitUtils; import com.rabbitmq.client.*; import java.io.IOException; public class Consumer { public static void main(String[] args) throws Exception{ //Get TCP long connection Connection conn = RabbitUtils.getConnection(); //Create a communication "channel", which is equivalent to a virtual connection in TCP Channel channel = conn.createChannel(); //Create a queue, declare and create a queue, and use it if it already exists //First parameter: queue name ID //The second parameter: whether to persist. false corresponds to non persistent data. If MQ stops, the data will be lost //The third parameter: whether to privatize the queue. false means that all consumers can access it. true means that only consumers who own it for the first time can always use it. Other consumers are not allowed to access it //Fourth: whether to delete automatically. false means that the queue will not be deleted automatically after the connection is stopped //Other additional parameters, null channel.queueDeclare(RabbitConstant.QUEUE_TEST,false, false, false, null); //Get data from MQ server //Create a message consumer //First parameter: queue name //The second parameter represents whether to automatically confirm the receipt of the message, and false represents manual programming to confirm the message, which is the recommended practice of MQ //The third parameter is passed into the implementation class of DefaultConsumer channel.basicConsume(RabbitConstant.QUEUE_TEST, false, new Reciver(channel)); } } class Reciver extends DefaultConsumer { private Channel channel; //Rewrite the constructor. The Channel object needs to be passed in from the outer layer and used in handleDelivery public Reciver(Channel channel) { super(channel); this.channel = channel; } @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { String message = new String(body); System.out.println("Message received by consumer:"+message); System.out.println("Message TagId: "+envelope.getDeliveryTag()); //false only confirms to sign in the current message. When set to true, it means to sign in all unsigned messages of the consumer channel.basicAck(envelope.getDeliveryTag(), false); }
I start the consumer first and then the producer, so that as soon as the producer produces the news, the consumer can consume immediately.
Work queues work queue mode:
In order to distinguish and understand, I create a virtual machine for each mode. Here, I go to the rabbitMq control page to create a virtual machine
Modify virtual machine of tool class
In order to simulate some businesses, a user-defined entity class is used here to send messages, so I created a new user-defined entity class
/** * Custom entity class: send content */ public class SenderContent { private String name; private String content; public SenderContent(String name, String content) { this.name = name; this.content = content; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } }
producer:
import com.liao.rabbitmq.utils.RabbitConstant; import com.liao.rabbitmq.utils.RabbitUtils; import com.google.gson.Gson; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; /** * Generator */ public class Producer { public static void main(String[] args) throws Exception { Connection connection = RabbitUtils.getConnection(); Channel channel = connection.createChannel(); channel.queueDeclare(RabbitConstant.QUEUE_SENDER_CONTENT, false, false, false, null); for(int i = 1 ; i <= 100 ; i++) { SenderContent senderContent = new SenderContent("full name:" + i, "Content:" + i); String jsonSMS = new Gson().toJson(senderContent); channel.basicPublish("" , RabbitConstant.QUEUE_SENDER_CONTENT , null , jsonSMS.getBytes()); } System.out.println("Sending data succeeded"); channel.close(); connection.close(); } }
Consumer I:
import com.liao.rabbitmq.utils.RabbitConstant; import com.liao.rabbitmq.utils.RabbitUtils; import com.rabbitmq.client.*; import java.io.IOException; /** * Consumer 1 */ public class ConsumerOne { public static void main(String[] args) throws Exception { Connection connection = RabbitUtils.getConnection(); final Channel channel = connection.createChannel(); channel.queueDeclare(RabbitConstant.QUEUE_SENDER_CONTENT, false, false, false, null); //If basicQos (1) is not written, MQ automatically sends all requests to all consumers on average //basicQos,MQ no longer sends multiple requests to consumers at one time, but after the consumer processes a message (after confirmation), it obtains a new request from the queue channel.basicQos(1);//Take one after processing channel.basicConsume(RabbitConstant.QUEUE_SENDER_CONTENT , false , new DefaultConsumer(channel){ @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { String jsonSMS = new String(body); System.out.println("ConsumerOne-Sent successfully:" + jsonSMS); try { Thread.sleep(10); } catch (Exception e) { e.printStackTrace(); } //Confirm receipt channel.basicAck(envelope.getDeliveryTag() , false); } }); } }
Consumer II:
import com.liao.rabbitmq.utils.RabbitConstant; import com.liao.rabbitmq.utils.RabbitUtils; import com.rabbitmq.client.*; import java.io.IOException; /** * Consumer 2 */ public class ConsumerTwo { public static void main(String[] args) throws IOException { Connection connection = RabbitUtils.getConnection(); final Channel channel = connection.createChannel(); channel.queueDeclare(RabbitConstant.QUEUE_SENDER_CONTENT, false, false, false, null); //If basicQos (1) is not written, MQ automatically sends all requests to all consumers on average //basicQos,MQ no longer sends multiple requests to consumers at one time, but after the consumer processes a message (after confirmation), it obtains a new request from the queue channel.basicQos(1);//Take one after processing channel.basicConsume(RabbitConstant.QUEUE_SENDER_CONTENT , false , new DefaultConsumer(channel){ @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { String jsonSMS = new String(body); System.out.println("ConsumerTwo-Sent successfully:" + jsonSMS); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } //Confirm receipt channel.basicAck(envelope.getDeliveryTag() , false); } }); } }
Consumer III:
import com.liao.rabbitmq.utils.RabbitConstant; import com.liao.rabbitmq.utils.RabbitUtils; import com.rabbitmq.client.*; import java.io.IOException; /** * Consumer 3 */ public class ConsumerThree { public static void main(String[] args) throws IOException { Connection connection = RabbitUtils.getConnection(); final Channel channel = connection.createChannel(); channel.queueDeclare(RabbitConstant.QUEUE_SENDER_CONTENT, false, false, false, null); //If basicQos (1) is not written, MQ automatically sends all requests to all consumers on average //basicQos,MQ no longer sends multiple requests to consumers at one time, but after the consumer processes a message (after confirmation), it obtains a new request from the queue channel.basicQos(1);//Take one after processing channel.basicConsume(RabbitConstant.QUEUE_SENDER_CONTENT , false , new DefaultConsumer(channel){ @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { String jsonSMS = new String(body); System.out.println("ConsumerThree-Sent successfully:" + jsonSMS); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } //Confirm receipt channel.basicAck(envelope.getDeliveryTag() , false); } }); } }
Here, different sleep times are set for each consumer. It is demonstrated that each consumer has different business processing time to view the message consumption
It can be seen that consumer one consumes the most and consumer three consumes the least, because this is set in the code
channel.basicQos(1);//Take one after processing
After the consumer has processed a message (after confirmation), it gets a new message from the queue.
Pub/Sub subscription mode:
In order to distinguish and understand, I create a virtual machine for each mode. Here, I go to the rabbitMq control page to create a virtual machine
Create a switch: here, the broadcast mode is used as the type of switch for demonstration
Modify virtual machine of tool class
producer:
import com.liao.rabbitmq.utils.RabbitConstant; import com.liao.rabbitmq.utils.RabbitUtils; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import java.util.Scanner; /** * Publisher */ public class Producer { public static void main(String[] args) throws Exception { Connection connection = RabbitUtils.getConnection(); //keyboard entry String input = new Scanner(System.in).next(); Channel channel = connection.createChannel(); //The first parameter is the switch name, and other parameters are the same as before channel.basicPublish(RabbitConstant.EXCHANGE_CONTENT,"" , null , input.getBytes()); channel.close(); connection.close(); } }
Consumer I:
import com.liao.rabbitmq.utils.RabbitConstant; import com.liao.rabbitmq.utils.RabbitUtils; import com.rabbitmq.client.*; import java.io.IOException; /** * Consumer 1 */ public class ConsumerOne { public static void main(String[] args) throws IOException { //Get TCP long connection Connection connection = RabbitUtils.getConnection(); //Get virtual connection final Channel channel = connection.createChannel(); //Declare queue information channel.queueDeclare(RabbitConstant.QUEUE_ONE, false, false, false, null); //queueBind is used to bind queues to switches //Parameter 1: queue name parameter 2: interactive machine name parameter 3: routing key (temporarily unavailable) channel.queueBind(RabbitConstant.QUEUE_ONE, RabbitConstant.EXCHANGE_CONTENT, ""); channel.basicQos(1); channel.basicConsume(RabbitConstant.QUEUE_ONE , false , new DefaultConsumer(channel){ @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { System.out.println("As soon as the consumer receives the message:" + new String(body)); channel.basicAck(envelope.getDeliveryTag() , false); } }); } }
Consumer II:
import com.liao.rabbitmq.utils.RabbitConstant; import com.liao.rabbitmq.utils.RabbitUtils; import com.rabbitmq.client.*; import java.io.IOException; /** * Consumer 2 */ public class ConsumerTwo { public static void main(String[] args) throws IOException { //Get TCP long connection Connection connection = RabbitUtils.getConnection(); //Get virtual connection final Channel channel = connection.createChannel(); //Declare queue information channel.queueDeclare(RabbitConstant.QUEUE_TWO, false, false, false, null); //queueBind is used to bind queues to switches //Parameter 1: queue name parameter 2: interactive machine name parameter 3: routing key (temporarily unavailable) channel.queueBind(RabbitConstant.QUEUE_TWO, RabbitConstant.EXCHANGE_CONTENT, ""); channel.basicQos(1); channel.basicConsume(RabbitConstant.QUEUE_TWO , false , new DefaultConsumer(channel){ @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { System.out.println("Consumer 2 receives information:" + new String(body)); channel.basicAck(envelope.getDeliveryTag() , false); } }); } }
Demonstration effect:
Routing mode:
In order to distinguish and understand, I create a virtual machine for each mode. Here, I go to the rabbitMq control page to create a virtual machine
Modify virtual machine of tool class
Create switch: the switch type here must be changed to routing mode. If it is still fanout in broadcast mode, the effect will be the same as that in publish and subscription mode above.
Error instance:
Correct example:
producer:
import com.liao.rabbitmq.utils.RabbitConstant; import com.liao.rabbitmq.utils.RabbitUtils; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; /** * Publisher */ public class Producer { public static void main(String[] args) throws Exception { Map area = new LinkedHashMap<String, String>(); area.put("routing.one.a.20201127", "Changsha, Hunan, China 20201127 private data"); area.put("routing.one.d.20201128", "China Hebei Shijiazhuang 20201128 private data"); area.put("routing.two.b.20201127", "Wuhan, Hubei, China 20201127 private data"); area.put("routing.two.e.20201128", "Wuhan, Hubei, China 20201128 private data"); area.put("routing.three.c.20201127", "China Hunan Zhuzhou 20201128 private data"); area.put("routing.three.f.20201128", "Zhengzhou, Henan, China 20201128 private data"); area.put("us.one.a.20201127", "Private data in Los Angeles, California 20201127"); area.put("us.two.b.20201128", "Private data in Los Angeles, California 20201128"); Connection connection = RabbitUtils.getConnection(); Channel channel = connection.createChannel(); Iterator<Map.Entry<String, String>> itr = area.entrySet().iterator(); while (itr.hasNext()) { Map.Entry<String, String> me = itr.next(); //The first parameter is the switch name, and the second parameter is the routing key of the message channel.basicPublish(RabbitConstant.EXCHANGE_CONTENT_ROUTING,me.getKey() , null , me.getValue().getBytes()); } channel.close(); connection.close(); } }
Consumer I:
import com.liao.rabbitmq.utils.RabbitConstant; import com.liao.rabbitmq.utils.RabbitUtils; import com.rabbitmq.client.*; import java.io.IOException; /** * Consumer 1 */ public class ConsumerOne { public static void main(String[] args) throws IOException { Connection connection = RabbitUtils.getConnection(); final Channel channel = connection.createChannel(); channel.queueDeclare(RabbitConstant.QUEUE_ONE, false, false, false, null); //queueBind is used to bind queues to switches //Parameter 1: queue name parameter 2: interactive machine name parameter 3: routing key channel.queueBind(RabbitConstant.QUEUE_ONE, RabbitConstant.EXCHANGE_CONTENT_ROUTING, "routing.one.a.20201127"); channel.queueBind(RabbitConstant.QUEUE_ONE, RabbitConstant.EXCHANGE_CONTENT_ROUTING, "us.one.a.20201127"); channel.basicQos(1); channel.basicConsume(RabbitConstant.QUEUE_ONE , false , new DefaultConsumer(channel){ @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { System.out.println("Consumer 1 receives a message:" + new String(body)); channel.basicAck(envelope.getDeliveryTag() , false); } }); } }
Consumer II:
import com.liao.rabbitmq.utils.RabbitConstant; import com.liao.rabbitmq.utils.RabbitUtils; import com.rabbitmq.client.*; import java.io.IOException; /** * Consumer 2 */ public class ConsumerTwo { public static void main(String[] args) throws IOException { Connection connection = RabbitUtils.getConnection(); final Channel channel = connection.createChannel(); channel.queueDeclare(RabbitConstant.QUEUE_TWO, false, false, false, null); //queueBind is used to bind queues to switches //Parameter 1: queue name parameter 2: interactive machine name parameter 3: routing key channel.queueBind(RabbitConstant.QUEUE_TWO, RabbitConstant.EXCHANGE_CONTENT_ROUTING, "routing.one.d.20201128"); channel.queueBind(RabbitConstant.QUEUE_TWO, RabbitConstant.EXCHANGE_CONTENT_ROUTING, "routing.two.e.20201128"); channel.basicQos(1); channel.basicConsume(RabbitConstant.QUEUE_TWO , false , new DefaultConsumer(channel){ @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { System.out.println("Consumer 2 receives information:" + new String(body)); channel.basicAck(envelope.getDeliveryTag() , false); } }); } }
effect:
The routing mode requires the consumer to specify a routing key
Topics wildcard mode:
In order to distinguish and understand, I create a virtual machine for each mode. Here, I go to the rabbitMq control page to create a virtual machine
Modify virtual machine of tool class
Create an interactive machine of type topic
producer:
import com.liao.rabbitmq.utils.RabbitConstant; import com.liao.rabbitmq.utils.RabbitUtils; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; /** * Publisher */ public class Producer { public static void main(String[] args) throws Exception { Map area = new LinkedHashMap<String, String>(); area.put("routing.one.a.20201127", "Changsha, Hunan, China 20201127 private data"); area.put("routing.one.d.20201128", "China Hebei Shijiazhuang 20201128 private data"); area.put("routing.two.b.20201127", "Wuhan, Hubei, China 20201127 private data"); area.put("routing.two.e.20201128", "Wuhan, Hubei, China 20201128 private data"); area.put("routing.three.c.20201127", "China Hunan Zhuzhou 20201128 private data"); area.put("routing.three.f.20201128", "Zhengzhou, Henan, China 20201128 private data"); area.put("us.one.a.20201127", "Private data in Los Angeles, California 20201127"); area.put("us.two.b.20201128", "Private data in Los Angeles, California 20201128"); Connection connection = RabbitUtils.getConnection(); Channel channel = connection.createChannel(); Iterator<Map.Entry<String, String>> itr = area.entrySet().iterator(); while (itr.hasNext()) { Map.Entry<String, String> me = itr.next(); //The first parameter is the switch name, and the second parameter is the routing key of the message channel.basicPublish(RabbitConstant.EXCHANGE_CONTENT_TOPIC,me.getKey() , null , me.getValue().getBytes()); } channel.close(); connection.close(); } }
Consumer I:
import com.liao.rabbitmq.utils.RabbitConstant; import com.liao.rabbitmq.utils.RabbitUtils; import com.rabbitmq.client.*; import java.io.IOException; /** * Consumer 1 */ public class ConsumerOne { public static void main(String[] args) throws IOException { Connection connection = RabbitUtils.getConnection(); final Channel channel = connection.createChannel(); channel.queueDeclare(RabbitConstant.QUEUE_ONE, false, false, false, null); //queueBind is used to bind queues to switches //Parameter 1: queue name parameter 2: interactive machine name parameter 3: routing key channel.queueBind(RabbitConstant.QUEUE_ONE, RabbitConstant.EXCHANGE_CONTENT_TOPIC, "*.*.*.20201127"); // channel.queueBind(RabbitConstant.QUEUE_ONE, RabbitConstant.EXCHANGE_CONTENT_TOPIC, "us.two.b.20201128"); channel.basicQos(1); channel.basicConsume(RabbitConstant.QUEUE_ONE , false , new DefaultConsumer(channel){ @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { System.out.println("Consumer 1 receives a message:" + new String(body)); channel.basicAck(envelope.getDeliveryTag() , false); } }); } }
Consumer II:
import com.liao.rabbitmq.utils.RabbitConstant; import com.liao.rabbitmq.utils.RabbitUtils; import com.rabbitmq.client.*; import java.io.IOException; /** * Consumer 2 */ public class ConsumerTwo { public static void main(String[] args) throws IOException { //Get TCP long connection Connection connection = RabbitUtils.getConnection(); //Get virtual connection final Channel channel = connection.createChannel(); //Declare queue information channel.queueDeclare(RabbitConstant.QUEUE_TWO, false, false, false, null); //Specify the relationship between the queue and the switch and the routing key channel.queueBind(RabbitConstant.QUEUE_TWO, RabbitConstant.EXCHANGE_CONTENT_TOPIC, "us.#"); channel.basicQos(1); channel.basicConsume(RabbitConstant.QUEUE_TWO , false , new DefaultConsumer(channel){ @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { System.out.println("Consumer 2 receives information:" + new String(body)); channel.basicAck(envelope.getDeliveryTag() , false); } }); } }
effect:
Note: if you want to switch modes for testing, you only need to modify the virtual machine in the tool class. The previous names are the same to reflect that each virtual machine is isolated at this time, so it doesn't matter if the key is the same.
2, Message confirmation mechanism: confirm and return status
Continuous updating
summary
Tip: here is a summary of the article:
For example, the above is what we want to talk about today. This paper only briefly introduces the basic concepts and several working modes of RabbitMQ, and strengthens the understanding of RabbitMQ's theory through a simple Demo demonstration. The combination of theory and practice can help you understand it quickly.