The MQ whole process (message queue) is also known as the information queuing, which is a middleware for asynchronous communication. Can be understood as the Post office, the sender sends the message to the Post office, then the Post office helps us to send to the specific receiver, the specific sending process and the time is irrelevant to us, the common MQ also Kafka, Activemq, Zeromq, RABBITMQ and so on.
RabbitMQ
RABBITMQ is a follow the AMQP protocol, developed by the high concurrency-oriented Erlang language, which is used in real-time high reliability-demanding messaging, supports multiple language clients, and supports deferred queuing.
Basic concepts
Broker: Server entity for Message Queuing
Exchange: A message switch that specifies what rules the message is routed to which queue
Queue: Message Queuing vector, each message will be put into one or more queues
Binding: Bind, which is primarily to bind exchange and queue according to routing rules
Routing key: Routing keyword, exchange message delivery based on this keyword
Vhost: Virtual host, a broker can open multiple vhost, as a separate user permissions separation
Producer: Message producer, the program that delivers the message
Consumer: Message consumers, programs that receive messages
Channel: The message channels, in each connection of the client, can establish multiple channel, each channel represents a session task
Common Application Scenarios
1. E-mail: After the user registers the delivery message to the RABBITMQ, the message consumer sends the message asynchronously, improves the system response speed.
2. Traffic cutting front: Generally in the second kill activity in a wide range of applications, seconds to kill because of excessive traffic, resulting in the application hangs, in order to solve this problem, generally in the application front-end to join the message queue. For controlling the number of active people, discard orders that exceed this threshold value directly. A high-flow crushing application that alleviates the end time.
3. Order timeout: Using the RABBITMQ delay queue, it is easy to implement the order super function, for example, the user did not pay the cancellation order after 30 minutes after placing the orders.
Import dependency
Adding SPRING-BOOT-STARTER-AMQP dependencies in Pom.xml
<dependency> <groupId>org.springframework.boot</groupId> <artifactId> Spring-boot-starter-amqp</artifactid></dependency>
Property configuration
Configure the RABBITMQ information in Application.yml, where the manual ACK switch is configured
Spring: rabbitmq: username:david 123456 host:localhost 5672 Virtual -host:/ listener: Simple : acknowledge-mode:manual #手动ACK does not turn on auto ack mode, The goal is to prevent error after the message is processed correctly the loss defaults to none
defining queues
Packagecom.spring.boot.utils;ImportOrg.springframework.amqp.core.Queue;ImportOrg.springframework.context.annotation.Bean;Importorg.springframework.context.annotation.Configuration; @Configuration Public classRabbitconfig { Public Static FinalString default_book_queue = "Dev.book.register.default.queue"; Public Static FinalString manual_book_queue = "Dev.book.register.manual.queue"; @Bean PublicQueue Defaultbookqueue () {//parameter 1 queue name, parameter 2 is persisted processing return NewQueue (Default_book_queue,true); } @Bean Queue Manualbookqueue () {return NewQueue (Manual_book_queue,true); }}
Entity class
PackageCom.spring.boot.bean;Importjava.io.Serializable; Public classBookImplementsserializable{PrivateInteger ID; PrivateString name; PublicInteger getId () {returnID; } Public voidsetId (Integer id) { This. ID =ID; } PublicString GetName () {returnname; } Public voidsetName (String name) { This. Name =name; }}
Controller
Create a new Bookcontroller for message sending
PackageCom.spring.boot.controller;ImportCom.spring.boot.bean.Book;ImportCom.spring.boot.utils.RabbitConfig;Importorg.springframework.amqp.rabbit.core.RabbitTemplate;Importorg.springframework.beans.factory.annotation.Autowired;Importorg.springframework.web.bind.annotation.GetMapping;Importorg.springframework.web.bind.annotation.RequestMapping;ImportOrg.springframework.web.bind.annotation.RestController, @RestController @requestmapping ("/books") Public classBookcontroller {//Spring Boot 2.x version recommends constructor injection instead of attribute injection Private Finalrabbittemplate rabbittemplate; @Autowired PublicBookcontroller (rabbittemplate rabbittemplate) { This. rabbittemplate =rabbittemplate; } @GetMapping ("/defaultmessage") Public voidDefaultmessage () { Book Book=NewBook (); Book.setid (1); Book.setname ("Hello RabbitMQ"); This. Rabbittemplate.convertandsend (Rabbitconfig.default_book_queue, book); This. Rabbittemplate.convertandsend (Rabbitconfig.manual_book_queue, book); }}
Message Consumers
By default, SPRING-BOOT-DATA-AMQP is the automatic ACK mechanism, which means that MQ will automatically help us to ACK after the message is consumed, so that the dependency has a problem: if the error, the message will not be lost, will be unlimited cycle consumption, it is easy to disk space consumption, Although it is possible to configure the number of consumption, this is not a good practice. At present, it is recommended that we manually ack and then transfer the consumption error message to the other message queue, do compensation processing
PackageCom.spring.boot.handler;ImportCom.rabbitmq.client.Channel;ImportCom.spring.boot.bean.Book;ImportCom.spring.boot.utils.RabbitConfig;ImportOrg.springframework.amqp.core.Message;ImportOrg.springframework.amqp.rabbit.annotation.RabbitListener;Importorg.springframework.stereotype.Component;Importjava.io.IOException; @Component Public classBookhandler {@RabbitListener (Queues={rabbitconfig.default_book_queue}) Public voidListenerautoack (book book, Message Message,channel Channel)throwsIOException {Final LongDeliverytag =message.getmessageproperties (). Getdeliverytag (); Try{System.out.println ("Listenerautoack heard the message:" +book.tostring ()); //TODO notifies MQ that it has been consumed to complete the ACK.Channel.basicack (Deliverytag,false); } Catch(IOException e) {//TODO processing failed, re-pressing into MQChannel.basicrecover (); E.printstacktrace (); }} @RabbitListener (Queues={rabbitconfig.manual_book_queue}) Public voidlistenermanualack (book Book,message Message,channel Channel) {System.out.println ("Listenermanualack heard the message:" +book.tostring ()); Try{channel.basicack (Message.getmessageproperties (). Getdeliverytag (),false); } Catch(IOException e) {//error-tolerant processing, such as transferring the current message to another queueE.printstacktrace (); } }}
Test: Start Project input Path Http://localhost:8088/books/defaultMessage
Spring Boot (RABBITMQ) Message Queuing