This is the 17th day of my participation in the August More text Challenge. For details, see: August More Text Challenge

🚨 If you are not already familiar with the four types of switches in RabbitMQ, it is recommended that you learn about the four types of switches in RabbitMQ before reading this article. For more information, see my other article πŸ‘‰ Four Types of Switches in RabbitMQ)

🎏RabbitMQ Six working modes

Simple Mode

  • Simple mode is a simple mode of sending and receiving. As shown in the figure above, P is the message producer, the red part is the message queue, and C is the message consumer. At this point, you may ask, what about the switch? In simple mode we do not need to specify the switch, RabbitMQ will go through the defaultDefault AMQP switchIt is a Direct type switch, and the binding key when the queue is bound to it is actually the name of the queue. More information can be found in another of my articles, πŸ‘‰RabbitMQ There are four types of switches)

Code implementation
  • First, define a queue queue5 without defining the switch
@bean public Queue queue5(){return new Queue("queue5"); }Copy the code
  • producers
@test void contextLoads() {// no switch is required, Pass in an empty string // and send the message to queue Queue5, where queue5 is actually the routing key // the message will only be delivered to Queue5 if it is the same as the binding key used when the queue is bound to the default switch Queue5 rabbitTemplate. ConvertAndSend (" ", ", "the Programmer do not drink milk tea"); }Copy the code
  • consumers
@Component public class Consumer1 { @RabbitListener(queues = "queue5") public void receiverMessage(Object msg, Throws IOException {system.out.println (" received Message: "+ MSG); channel.basicAck(message.getMessageProperties().getDeliveryTag(),false); }}Copy the code
  • Program output:
Successful delivery received message: [headers={}, contentType=text/plain, contentEncoding= utF-8, contentLength=0, contentEncoding= utF-8, contentLength=0, receivedDeliveryMode=PERSISTENT, priority=0, redelivered=false, receivedExchange=, receivedRoutingKey=queue5, deliveryTag=1, consumerTag=amq.ctag-Kmxu_O-84ooZv_N2AjkkEg, consumerQueue=queue5])Copy the code

Can be seen from the results, we in the absence of defined statement switches, and can be successfully delivered to the queue, and consumers can consume news, thus confirms what we mentioned above, simple mode is the default switches to the message delivery to the queue, rather than say there is no switch.

Two, work mode

In work mode, the default AMQP switch is used. In work mode, multiple consumers can listen on the same Queue. In this case, the messages in the Queue are evenly distributed among consumers for processing, rather than each consumer receiving all the messages and processing them. When there are multiple consumers, which one will consume our information, and how should we balance the amount of information that consumers consume?

There are two main modes of work:

  • πŸš— Polling distribution: Each consumer consumes one item and the distribution is evenly distributed. In WOEK mode, polling distribution is adopted by default. Polling distribution is simple to demonstrate without writing code. For example, if the producer sends six messages to the queue, and if there are three consumers listening to the queue at the same time, then the three consumers will each get two messages. Fair distribution is described below.

  • ✈ Fair distribution: fair distribution according to the consumer’s consumption ability, the fast share, the slow share, the expert more work.

Fair distribution model
  1. In the fair distribution mode, we need to change the RabbitMQ configuration. First, we need to change the message acknowledgment mode to manual acknowledgment. Second, we need to change the pre-processing mode to read one message at a time.
RabbitMq: host: 192.168.180.130 Port: 5672 username: admin Password: admin Virtual-host: > > < span style = "max-width: 0; max-width: 0; max-width: 0; # Consumer manual acknowledgement -mode: manual # Pre-fetch mode: read one message at a time, and not process the next message until the consumer returns acknowledgementCopy the code
  • We then ask the producer to post four messages to the queue and prepare two consumers to consume the messages in the queue.

    • Producers:
    @test void contextLoads() {// Send a message to queue5, which is a routing key. // Only send a message to queue5 for (int) when queue5 is bound to the switch  i = 1; i <5; I++) {rabbitTemplate. ConvertAndSend (" ", "queue5", "message" + I + "the Programmer do not drink milk tea", the new CorrelationData (I + "")); }}Copy the code
    • Consumer 1, consumption ability is poor, consumption process needs"Sleeping πŸ›Œ"
    Component @RabbitListener(queues = "queue5") public class Consumer1 { @RabbitHandler public void receiverMessage(Object MSG, Channel Channel,Message Message) throws IOException, InterruptedException {Thread. Println (" customer 1 received message: "+ MSG); channel.basicAck(message.getMessageProperties().getDeliveryTag(),false); }}Copy the code
    • Consumer 2, strong spending power
    @Component @RabbitListener(queues = "queue5") public class Consumer2 { @RabbitHandler public void receiverMessage(Object MSG, Channel Channel,Message Message) throws IOException, InterruptedException {system.out.println (" Consumer 2 received Message: "+ MSG); channel.basicAck(message.getMessageProperties().getDeliveryTag(),false); }}Copy the code
  • The running results are as follows:

By above may know, there are 4 messages in the queue, the consumption ability of consumers to buy 2 3 messages, and consumption ability weak consumer spending only 1 message, 1 so it is in fair distribution mode, out whoever needs of consumer 1 don’t sleep, so its consumption ability is strong, suddenly spending three messages, Consumer 2, on the other hand, has to sleep in while he’s spending because he has poor spending power, so he can only consume 1 message.

Application scenarios

🎁 For example, in a shopping platform, there are two order systems. When a user has placed an order, the order information will be sent to RabbitMQ. Only one order system needs to get the order information from the queue and process the user’s order.

Publish/Subscribe

In Publish/Subscribe, the producer sends messages to the Broker, the switch delivers messages to each queue bound to it, and each consumer listens to its own queue for messages sent by the producer. So this is just like the fanout type switch that we talked about earlier, all the queues that are bound to a Fanout type switch are going to receive the message that it sends, and all the queues are going to share the message.

Code implementation
  1. First we need to define a switch of type Fanout and two queues queue6, queue7, and bind queue6 and Queue7 to the switch as follows:
@bean public FanoutExchange FanoutExchange(){return new FanoutExchange("PS_fanoutExchange"); } @bean public Queue queue6(){return new Queue(" Queue 6");} @bean public Queue queue6(){return new Queue(" Queue 6"); } @Bean public Queue queue7(){ return new Queue("queue7"); } public Binding binding6(){return BindingBuilder. Bind (queue6()). To (fanoutExchange()); } public Binding binding7(){return bindingBuild.bind (queue7()).to(fanoutExchange()); }Copy the code
  1. Define two consumers, consumer 1 listens to queue6 and consumer 2 listens to queue7
    • Consumer 1
    @component public class psConsumer1 {// queues = "queue6" public void receiver(Object MSG, queues = "queue6") Throws IOException {system.out. println(" consumer 1 of queue6 receives Message: "+ MSG); / / manual ACK channel. BasicAck (message. GetMessageProperties () getDeliveryTag (), false); }}Copy the code
    • Consumer 2
    @component public class psConsumer2 {// queues (queues = "queue7") public void receiver(Object MSG, Throws IOException {system.out. println(" consumer 2 of queue7 receives Message: "+ MSG); / / manual ACK channel. BasicAck (message. GetMessageProperties () getDeliveryTag (), false); }}Copy the code
  2. The producer sends a message without specifying a routing key
@ Test void PublicSubscribe () {rabbitTemplate. ConvertAndSend (" PS_fanoutExchange ", ""," release a subscription model ", new CorrelationData(" Do not drink milk tea Programmer"); }Copy the code

🎏 The running result is as follows:

From the above results, we can see that the producer only sends one message, and both consumers receive the message sent by the producer. This indicates that in the Publish/Subscribe mode, any queue bound to the switch can receive the message sent by the producer. Thus, all consumers listening on the corresponding queue can get the messages that the switch delivers to the queue.

Application scenarios

For example, in a user registration service, after the user submits the registration information, the information is sent to RabbitMQ, and the SMS service and mail service get the user information from the queues respectively, and complete the SMS and mail sending after the user registration.

Routing Mode

In routing mode, the corresponding switch is the Direct switch. When the producer sends a message, it needs to specify a routing key. The switch will post the message to the specified queue according to the routing key. Let’s go straight to the example.

Code implementation
  1. Declare a Direct switch namedRouting_DirectDeclare two queuesQueue8, queue9, queuequeue8Bind to the exchange and specify the binding key asorangeThe queuequeue9Bind to the switch and specify the binding key asgreen`
@bean public DirectExchange DirectExchange(){return new DirectExchange("Routing_Direct"); } @bean public Queue queue8(){return new Queue("queue8"); } @Bean public Queue queue9(){ return new Queue("queue9"); } // Bind queue8 to the switch, Orange @bean public binding bindingQueue8(){return BindingBuilder.bind(queue8()).to(directExchange()).with("orange"); } // Bind the queue e9 to the switch, Green @bean public binding bindingQueue9(){return BindingBuilder.bind(queue9()).to(directExchange()).with("green"); }Copy the code
  1. Have two consumers listening for QueuE8 and QueuE9
  • Consumer1
@Component public class R_Consumer1 { @RabbitListener(queues = "queue8") public void getMessage(Object msg, Throws IOException {system.out. println(" queue8: "+ MSG); / / manual confirmation channel. BasicAck (message. GetMessageProperties () getDeliveryTag (), false); }}Copy the code
  • Consumer2
@Component public class R_Consumer2 { @RabbitListener(queues = "queue9") public void getMessage(Object msg, Throws IOException {system.out. println(" the Message obtained by queue9 of consumer 2 is: "+ MSG); / / manual confirmation channel. BasicAck (message. GetMessageProperties () getDeliveryTag (), false); }}Copy the code
  1. The producer sends a message with the specified routing key asorange
@ Test void RoutingModelTest () {rabbitTemplate. ConvertAndSend (" Routing_Direct ", "orange", "the Programmer like orange do not drink milk tea", new CorrelationData("orange")); }Copy the code

The running results are as follows:

It is clear that only consumer 1 will receive the message, since the routing key and queue queue8 are the same as the binding key of the switch. The message will be sent to queue Queue8, which the consumer listens to, so only consumer 1 will receive the message.

5. Topic mode

The Topic Topic pattern uses topic-type switches and therefore supports fuzzy matching where messages can be delivered to one or more queues. When the producer sends a message, it specifies a routing key. Based on the routing key, the Topic exchange will find all queues that match the binding key rule specified when the queue is bound to the switch and will post the message to those queues. As shown in the figure above, when sending messages, specify routing key asa.orange.b(Binding key =*.orange.*), the message is delivered to the Q1 queue and not to the Q2 queue. Here is the code to demonstrate:

Code implementation
  • Declare a Topic switch and two queues queue10 and Queue11queue10Bind to the switch and specify the binding key as*.orange.*The queuequeue11Bind to the switch and specify the binding key as*.*.rabbit.
@bean public TopicExchange directExchange(){return new TopicE@Bean public TopicExchange directExchange(){ return new TopicExchange("Exchange_Topic"); } @bean public Queue queue10(){return new Queue("queue10"); } @Bean public Queue queue11(){ return new Queue("queue11"); } // Bind queue10 to the switch, Orange.* @bean public binding bindingQueue8(){return BindingBuilder.bind(queue10()).to(directExchange()).with("*.orange.*"); } // Bind queue11 to the switch, *.*.rabbit@bean public binding bindingQueue9(){return BindingBuilder.bind(queue11()).to(directExchange()).with("*.*.rabbit"); }Copy the code
  • Prepare two consumers to listen to Queue10 and Queue11

    • Consumer1
      @Component public class T_Consumer1 { @RabbitListener(queues = "queue10") public void getMessage(Object msg, Throws IOException {system.out. println(" Consumer 1 listens to queue queue10 to obtain messages: "+ MSG); / / manual confirmation channel. BasicAck (message. GetMessageProperties () getDeliveryTag (), false); }}Copy the code
    • Consumer2
    @Component public class T_Consumer2 { @RabbitListener(queues = "queue11") public void getMessage(Object msg, Throws IOException {system.out. println(" Consumer 2 listens to queue Queue11 to obtain messages: "+ MSG); / / manual confirmation channel. BasicAck (message. GetMessageProperties () getDeliveryTag (), false); }}Copy the code
  1. The producer sends a message with the specified routing key asa.orange.b
@Test void TopicModelTest(){ Exchange_Topic rabbitTemplate. ConvertAndSend (", "" a.o range. B", "do not drink milk tea Programmer like a.o range. B", new CorrelationData ( "a.orange.b")); }Copy the code
  • The results

The message is delivered to queue Queue10 because the routing key a.orange.b matches queue10 with the switch’s binding key, so the message is delivered to Queue10 correctly.

6. RPC mode

RPC mode is a remote procedure call mode, so far not much, understanding is not deep enough, laterHave to upgradeπŸ‘¨πŸš€ and then add πŸ˜…

🎑 summary

RabbitMq operates on four types of switches, Simple mode, Work mode, and Routing Mode are implemented based on Direct switches (simple mode, work mode, and Direct mode are implemented based on default AMQP default switches). Publish /Subscribe is implemented on fanout type switches. Routing is based on; The Topic Topic pattern is implemented based on topic-type switches. In daily development, we will encounter a variety of business needs, so it is very important to master RabbitMQ these several working modes, with these foundations, we can according to the business needs and system performance consideration, reasonable use of RabbitMQ, our technology to better service for the business 🎬.

🏁 This is a detailed introduction to RabbitMQ modes. If there are any errors, please leave a comment to correct them. If you find this article helpful, please click πŸ‘ πŸ˜‹πŸ˜»πŸ˜

k3u1fbpfcp-watermark.image)