Rabbit MQ message queue
@[toc]
brief introduction
Advantage
erlang development, strong concurrency.
The community is active, with many users and strong stability.
Low latency
shortcoming
erlang language development, the domestic proficient is not much, in the future customization development is difficult.
Rabbit MQ working mode
1, "Hello World!" mode
Simple mode is the simplest case for Rabbit MQ to get started, including a producer and a consumer. There is no need to declare the switch (actually there is a default switch). After declaring a queue, the producer sends it here, and the consumer listens to the queue and responds to the message.
Application scenario: such as chat between two users.
2. Work queues mode
Work queue mode assigns tasks among workers (competitive consumer mode), which is a simple mode with multiple consumers. Multiple consumers listen to the queue together. Rabbit MQ will ensure that a message in the queue will only be consumed by one consumer.
Application scenario: for example, multiple users scramble for an order (remember to consider locking when competing for the same resource in high concurrency)
3. Publish/Subscribe mode
The publish / subscribe mode sends messages to many consumers at a time, and it is also a producer and multiple consumers. However, the mode needs to display the declaration switch. Bind multiple queues created with the switch. The producer sends messages to the switch, and the switch sends messages to the bound queues. The consumers of a queue consume the information in the queue.
Application scenario: mass sending an email and pushing an advertisement
4. Routing mode
Whether the routing mode selectively receives messages or displays the declaration switch, binds the queue with the switch, and the producer sends messages to the switch, the switch sends messages to the corresponding queue, and the corresponding consumer consumption information. However, when a queue binds to a switch, it needs to specify a routingkey. In this case, when the producer sends a message to the producer again, it will judge the specific routingkey value and send the message that meets the corresponding routingkey value to the corresponding queue.
Application scenario: encapsulating several types of error type notifications
5. Topics mode
The topic pattern receives messages according to the pattern (topic). Just like the routing pattern, it is no longer judged according to the specific routingkey value, but based on the fuzzy matching of routingkey value. Among them, the asterisk represents multiple words, and the pound sign represents one word.
More detailed information can be found on the official website: RabbitMQ official website
Switch mode
fanout mode: do not process the routing key, that is, there is no routingkey value. It is very similar to the subnet broadcast. Each host in the subnet gets a copy of the message.
direct mode: to process the routing key, you need to match the routing key to forward, that is, to exactly match the routingkey value.
topic mode: processing route key requires fuzzy matching of route key to forward, that is, the routingkey value on fuzzy matching.
Import RabbitMQ queue
RabbitMQ dependency and erlang language, click Download link on official website Download erlang.
click Download link on official website Download RabbitMQ.
When you install both, you can set the default settings all the way.
Start RabbitMQ service, input in cmd mode, enter the default installation path
C:\Program Files (x86)\RabbitMQ Server\rabbitmq_server-3.6.10\sbin
Input command
rabbitmq-plugins enable rabbitmq_management
Service started successfully, as shown in the figure
click http://localhost:15672/ , as shown in the figure below
New in pom.xml
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency>
Add to application.properties
# RabbitMQ spring.rabbitmq.host=127.0.0.1 spring.rabbitmq.port=5672 spring.rabbitmq.username=guest spring.rabbitmq.password=guest # Initialization value for concurrent consumers spring.rabbitmq.listener.concurrency=10 # Maximum concurrent consumers spring.rabbitmq.listener.max-concurrency=20 # The number of messages that can be pulled and processed each time each consumer listens spring.rabbitmq.listener.prefetch=5
Code actual combat
There is no switch specified for simple mode and work queue mode, and the subtleties of rabbitMQ cannot be reflected. Routing mode and principal mode both have routingkey value, so one of them is chosen. This paper takes publish / subscribe mode and routing mode as examples, and the rest can be compared. Incomplete writing, because this is a quick start to use the series, the shortest time and energy to understand the context, is the purpose of the series, human beings are afraid of obscure and long, like short and direct.
The directory after the new code is as follows
RabbitConfig.java
package com.example.config; import org.springframework.amqp.core.*; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class RabbitConfig { //==============Publish / subscribe mode============== //Queue A @Bean() public Queue queueA() { return new Queue("fanoutQueueA"); } //Queue B @Bean() public Queue queueB() { return new Queue("fanoutQueueB"); } //fanout switch in publish subscribe mode @Bean public FanoutExchange fanoutExchange() { return new FanoutExchange("fanoutExchange"); } // Bind queue A to fanout switch @Bean public Binding bindingWithQueueA() { return BindingBuilder.bind(queueA()).to(fanoutExchange()); } // Bind queue B to fanout switch @Bean public Binding bindingWithQueueB() { return BindingBuilder.bind(queueB()).to(fanoutExchange()); } //==============Routing mode============== //Queue C @Bean() public Queue queueC() { return new Queue("directQueueC"); } //Queue D @Bean() public Queue queueD() { return new Queue("directQueueD"); } //direct switch in publish subscribe mode @Bean public DirectExchange directExchange() { return new DirectExchange("directExchange"); } // Bind queue C to the direct switch @Bean public Binding bindingWithQueueC() { return BindingBuilder.bind(queueC()).to(directExchange()).with("directRoutingkey"); } // Bind queue B to the direct switch @Bean public Binding bindingWithQueueD() { return BindingBuilder.bind(queueD()).to(directExchange()).with("directRoutingkey"); } }
RabbitController.java
package com.example.controller; import com.example.service.IRabbitProducerService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller @RequestMapping("rabbit") public class RabbitController { @Autowired private IRabbitProducerService rabbitProducerService; @RequestMapping("/fanout") public void fanout() { for (int i = 0; i < 5; i++) { this.rabbitProducerService.producerFanout("In publish and subscribe mode" + i + "Bar information"); } } @RequestMapping("/direct") public void direct() { for (int i = 0; i < 5; i++) { this.rabbitProducerService.producerDirect("In routing mode" + i + "Bar information"); } } }
IRabbitProducerService.java
package com.example.service; public interface IRabbitProducerService { void producerFanout(String message); void producerDirect(String message); }
RabbitProducerServiceIml.java
package com.example.service; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service("rabbitProducerService") public class RabbitProducerServiceIml implements IRabbitProducerService { @Autowired RabbitTemplate rabbitTemplate; public void producerFanout(String message) { rabbitTemplate.convertAndSend("fanoutExchange", null, message); } public void producerDirect(String message) { rabbitTemplate.convertAndSend("directExchange", "directRoutingkey", message); } }
IRabbitConsumerService.java
package com.example.service; public interface IRabbitConsumerService { void consumerFanoutA(String message); void consumerFanoutB(String message); void consumerDirectC(String message); void consumerDirectD(String message); }
RabbitConsumerServiceIml.java
package com.example.service; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.stereotype.Component; @Component public class RabbitConsumerServiceIml implements IRabbitConsumerService { @RabbitListener(queues = "fanoutQueueA") public void consumerFanoutA(String message) { System.out.println("Consumer received queue A News in:" + message); } @RabbitListener(queues = "fanoutQueueB") public void consumerFanoutB(String message) { System.out.println("Consumer received queue B News in:" + message); } @RabbitListener(queues = "routingQueueC") public void consumerDirectC(String message) { System.out.println("Consumer received queue C News in:" + message); } @RabbitListener(queues = "routingQueueD") public void consumerDirectD(String message) { System.out.println("Consumer received queue D News in:" + message); } }
After starting the project, the browser enters http://localhost:8080/rabbit/fanout , (although the foreground will report an error, because this request only triggers the production of the message, there is no corresponding interface display. The produced message is sent to the queue through the switch, and the consumer listens to the queue and responds accordingly.) The effect diagram of using fanout switch to produce consumption message in publish / subscribe mode is as follows:;
Browser input http://localhost:8080/rabbit/direct , the effect diagram of using direct switch to produce consumption message in routing mode is as follows;
Note: if it's based on the series of articles in this article, since spring security has been configured in the beginning, you should remember to assign this address to the logged in user. Or open a super administrator account. You can access any directory of the project and use the administrator account to access these addresses.
So far, it's a long time. I wanted to finish writing the dead letter queue and the message confirmation mechanism. Think of this as a quick integration series, put the in-depth content into the in-depth series, and look forward to the follow-up to open up a new series of articles.