Introduction to RabbitMQ
RabbitMQ is a complete and reusable enterprise messaging system based on AMQP
MQ is the full name of Message Queue. Message Queue (MQ) is a method of communication between applications and applications. Applications communicate by reading and writing queued messages (data for applications) without a dedicated connection to link them. Message delivery refers to communication between programs by sending data in messages, rather than by directly calling each other, direct calls are usually used in techniques such as remote procedure calls. Queuing refers to the application communicating through a queue. The use of queues eliminates the requirement that both the receiving and sending application execute simultaneously.
AMQP is a protocol, a high-level abstraction layer message communication protocol.
Although there are many public standards in the world of synchronous messaging (such as COBAR IIOP, or SOAP, etc.), this is not the case in asynchronous message processing. Only large companies have some commercial implementations (such as Microsoft's MSMQ, IBM's Websphere MQ, etc.). Therefore, in June 2006, Cisco, Redhat, iMatix and others jointly formulated public standards for AMQP. In other words, AMQP is a protocol for asynchronous communication.
RabbitMQ usage scenarios
In the project, some time-consuming operations that do not require immediate return are extracted and processed asynchronously. This asynchronous processing greatly saves the server's request response time, thereby improving the system's throughput. However, most of them are not just not required to return instantly, and it doesn't matter whether the execution is successful or not. If you need instant return, you can use Dubbo. Spring boot integrates with Dubbo, you can watch Spring boot integration Dubbox
RabbitMQ Dependency
RabbitMQ is not a simple jar package (the Jar package only provides some basic communication functions with RabbitMQ itself). Similar to Dubbo, RabbitMQ also requires other software to run. The following is the software required for RabbitMQ to run.
1. Erlang
Since the RabbitMQ software itself is developed based on Erlang, if you want to run RabbitMQ, you must first follow Erlang
Erlang official website
Erlang download address
RabbitMQ
RabbitMQ is the core of implementing message queues
RabbitMQ official website
RabbitMQ Download
Configuring RabbitMQ
After the installation is completed, you need to complete some configuration before using RabbitMQ. You can directly use cmd to the sbin directory under the installation directory of RabbitMQ through command configuration, or you can directly find RabbitMQ Command Prompt (sbin dir) in the start menu to run sbin directly to the installation directory of RabbitMQ. For convenience, we first enable the management plug-in and execute the commands.
rabbitmq-plugins.bat enable rabbitmq_management
That's right, note that this is under Windows. If it's Linux, there is no bat suffix. Then we add a user, because the connection cannot be successful without users in the external network environment. Execute the Add user command
rabbitmqctl.bat add_user springboot password
springboot is the username and password is the password
Then, for the convenience of demonstration, we give springboot the administrator permissions to facilitate login to the management page
rabbitmqctl.bat set_user_tags springboot administrator
Give account permissions
rabbitmqctl.bat set_permissions -p / springboot .* .* .*
Then start the RabbitMQ service and visit the RabbitMQ management page http://localhost:15672 to see the login page. If there is no user created, you can use guest and guest to log in. If there is a user created, use the created user to log in. If there is a user created, use the created user to log in.
Create Springboot Project
Since I have already mentioned creating a spring boot project in the previous article many times, I won't say much here
Add RabbitMQ related dependencies
<!-- rabbitmq --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency>
That's right, just a little configuration, but I may not understand this way, so I'd better post all the configurations
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>wang.raye.rabbitmq</groupId> <artifactId>demo1</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>demo1</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties><parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.0.RELEASE</version> </parent> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <!-- Springboot --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- rabbitmq --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> </dependencies></project>
Because no other operations are done, the project currently mainly relies on two modules, one Sprig boot and one RabbitMQ
Add configuration class
package wang.raye.rabbitmq.demo1;import org.springframework.amqp.core.AcknowledgeMode; import org.springframework.amqp.core.Binding; import org.springframework.amqp.core.Binding; import org.springframework.amqp.core.BindingBuilder; import org.springframework.amqp.core.DirectExchange; import org.springframework.amqp.core.Message; import org.springframework.amqp.core.Queue; import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; import org.springframework.amqp.rabbit.connection.ConnectionFactory; import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener; import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;/** * Rabbitmq configuration class * @author Raye * @since October 12, 2016 10:57:44 */@Configuration public class RabbitMQConfig { /** Name of the message switch*/ public static final String EXCHANGE = "my-mq-exchange"; /** Queue key1*/ public static final String ROUTINGKEY1 = "queue_one_key1"; /** Queue key2*/ public static final String ROUTINGKEY2 = "queue_one_key2"; /** * Configuration link information* @return */ @Bean public ConnectionFactory connectionFactory() { CachingConnectionFactory connectionFactory = new CachingConnectionFactory("127.0.0.1",5672); connectionFactory.setUsername("springboot"); connectionFactory.setPassword("password"); connectionFactory.setVirtualHost("/"); connectionFactory.setPublisherConfirms(true); // Return connectionFactory must be set; } /** * Configure message switch* Configure FanoutExchange for consumers: Distribute messages to all bound queues, without the concept of routingkey HeadersExchange: match DirectExchange by adding attribute key-value: Distribute to the specified queue according to routingkey TopicExchange: Multi-key matching*/ @Bean public DirectExchange defaultExchange() { return new DirectExchange(EXCHANGE, true, false); } /** * Configure message queue 1 * Configure for consumers* @return */ @Bean public Queue queue() { return new Queue("queue_one", true); //Quantity persistent} /** * Bind message queue 1 with switch* Configure for consumers* @return */ @Bean public Binding binding() { return BindingBuilder.bind(queue()).to(defaultExchange()).with(RabbitMQConfig.ROUTINGKEY1); } /** * Configure message queue 2 * Configure for consumers* @return */ @Bean public Queue queue1() { return new Queue("queue_one1", true); //Quick persistence} /** * Bind message queue 2 with the switch* Configure for consumers* @return */ @Bean public Binding binding1() { return BindingBuilder.bind(queue1()).to(defaultExchange()).with(RabbitMQConfig.ROUTINGKEY2); } /** * Accept the message listening, this listener will accept the message from message queue 1* Configure for consumers* @return */ @Bean public SimpleMessageListenerContainer messageContainer() { SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory()); container.setQueues(queue()); container.setExposeListenerChannel(true); container.setMaxConcurrentConsumers(1); container.setConcurrentConsumers(1); container.setAcknowledgeMode(AcknowledgeMode.MANUAL); //Set confirmation mode manually confirm container.setMessageListener(new ChannelAwareMessageListener() { public void onMessage(Message message, com.rabbitmq.client.Channel channel) throws Exception { byte[] body = message.getBody(); System.out.println("Message received: " + new String(body)); channel.basicAck(message.getMessageProperties().getDeliveryTag(), false); //Confirm the message to consume successfully} }); return container; } /** * Accept the message listening, this listener will accept the message from message queue 1* Configuration for consumers* @return */ @Bean public SimpleMessageListenerContainer messageContainer2() { SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory()); container.setQueues(queue1()); container.setExposeListenerChannel(true); container.setMaxConcurrentConsumers(1); container.setConcurrentConsumers(1); container.setAcknowledgeMode(AcknowledgeMode.MANUAL); //Set the confirmation mode manually confirm container.setMessageListener(new ChannelAwareMessageListener() { public void onMessage(Message message, com.rabbitmq.client.Channel channel) throws Exception { byte[] body = message.getBody(); System.out.println("queue1 Message received: " + new String(body)); channel.basicAck(message.getMessageProperties().getDeliveryTag(), false); //Confirm the message to be consumed successfully} }); return container; } }Note that in order to better demonstrate how to configure, I configured two message queues. Except for where the link configuration is configured, the rest of this class is targeted at message consumers. Of course, both message consumers and message producers need to configure link information. For convenience, the message consumers and producers of this project are both in this project. Generally, the actual project will not be in the same project. Since the comments are very detailed, I won’t say much.
Send a message
In order to facilitate sending messages, I directly wrote a Controller to call the method of sending messages by accessing the interface. Without further ado, please add the code
package wang.raye.rabbitmq.demo1;import java.util.UUID;import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.amqp.rabbit.support.CorrelationData; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;/** * Test the Controller for RabbitMQ to send messages * @author Raye * */@RestControllerpublic class SendController implements RabbitTemplate.ConfirmCallback{ private RabbitTemplate rabbitTemplate; /** * Configure the rabbitTemplate to send messages. Because it is a constructor, Spring will be automatically injected without annotation (it should be a feature of the new version) * @param rabbitTemplate */ public SendController(RabbitTemplate rabbitTemplate){ this.rabbitTemplate = rabbitTemplate; //Set consumption callback this.rabbitTemplate.setConfirmCallback(this); } /** * Send a message to message queue 1* @param msg * @return */ @RequestMapping("send1") public String send1(String msg){ String uuid = UUID.randomUUID().toString(); CorrelationData correspondenceId = new CorrelationData(uuid); rabbitTemplate.convertAndSend(RabbitMQConfig.EXCHANGE, RabbitMQConfig.ROUTINGKEY1, msg, correspondenceId); return null; } /** * Send a message to message queue 2* @param msg * @return */ @RequestMapping("send2") public String send2(String msg){ String uuid = UUID.randomUUID().toString(); CorrelationData correlationId = new CorrelationData(uuid); rabbitTemplate.convertAndSend(RabbitMQConfig.EXCHANGE, RabbitMQConfig.ROUTINGKEY2, msg, correlationId); return null; } /** * Message callback, mainly implementing the RabbitTemplate.ConfirmCallback interface* Note that message callbacks can only represent successful messages sent to the RabbitMQ server, and cannot represent successful messages being processed and accepted */ public void confirm(CorrelationData correspondenceData, boolean ack, String cause) { System.out.println("Callback id:" + correlationData); if (ack) { System.out.println("Message consumption failed:" + cause+"/n resend"); } }}It should be noted that message callbacks can only represent the successful message being sent to the RabbitMQ server.
Then we start the project and visit http://localhost:8082/send1?msg=aaaa and you will find that the console output is
Received message: aaaa
Callback id:CorrelationData [id=37e6e913-835a-4eca-98d1-807325c5900f]
Successful consumption of news
Of course the callback id may be different. If we visit http://localhost:8082/send2?msg=bbbb, the output will be
queue1 Received message: bbbb
Callback id:CorrelationData [id=0cec7500-3117-4aa2-9ea5-4790879812d4]
Successful consumption of news
A few words at the end
Because this article mainly explains how to integrate RabbitMQ from zero to springboot, there is no explanation for a lot of information and usage of RabbitMQ. If you are not familiar with RabbitMQ itself, you can check out other articles about RabbitMQ, and attach the demo of this article.
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.