Spring Boot RabbitMQ Deferred message implementation full version

Source: Internet
Author: User
Tags sendmsg set time rabbitmq

Overview

Once to NetEase interview, the interviewer asked me a question, said

After the order is completed, if the user does not pay, need to cancel the order, what can be done

My answer was to scan the DB table with a timed task. The interviewer is not very satisfied with the proposed:

Do you have any other ways to use timed tasks that do not permit real-time notifications?

My answer was:

Can use the queue, after the order is finished, send a message to the queue, and specify the expiration time, the time to execute callback interface.

When the interviewer finishes listening, he stops asking. In fact, my thinking was right, but not very professional. Professional parlance is used 延迟消息 .

In fact, with scheduled tasks, there is a problem, the original business system hope 10 minutes later, if the order is not paid, immediately cancel the order, and release the merchandise inventory. However, once the data volume is large, it will be extended to obtain the unpaid order data time, some orders can be done less than 10 minutes after the cancellation, may be 15 minutes, 20 minutes or the like. In this way, inventory can not be released in time, it will affect the singular. The use of delayed messages, in theory, can be done according to the set time, the order cancellation operation.

At present, the article about using RABBITMQ to implement delay message, mostly is how to use the RABBITMQ dead-letter queue to achieve, the implementation of the scheme looks very cumbersome and complex, and still use the original RABBITMQ Client API to achieve, more verbose.

Spring Boot has already packaged the RABBITMQ Client API, which is a lot simpler to use, with a detailed description of how to use rabbitmq_delayed_message_exchange plug-ins and spring boot to implement deferred messages.

Software Preparation Erlang

Please refer to the installation of Erlang under WIN10

The version used in this article is:

Erlang 20.3

RabbitMQ

Please refer to the WIN10 installation RABBITMQ

This article uses the window version of RABBITMQ, the version number is:

3.7.4

Rabbitmq_delayed_message_exchange Plug-in

Plug - ins:

Http://www.rabbitmq.com/community-plugins.html

After opening the URL, Ctrl + F, search rabbitmq_delayed_message_exchange .

Remember, be sure to choose the version number, because I use RABBITMQ 3.7.4, so the corresponding rabbitmq_delayed_message_exchange plug-in must also choose 3.7.x.

If you don't have the right version, you'll encounter a variety of wonderful problems when using deferred messages, and you won't find a solution on the web. I have been tossing the whole night for this problem. Keep in mind that you want to choose the right plug-in version.

After downloading the plugin, place it in the directory under the RABBITMQ installation directory and plugins use the following command to start the plugin:

Rabbitmq-plugins Enable Rabbitmq_delayed_message_exchange

If the startup succeeds, the following information will appear:

The following plugins has been enabled:
Rabbitmq_delayed_message_exchange

After you start the plugin successfully, remember to restart the RABBITMQ for it to take effect.

Integrated RABBITMQ

This is very simple and is added directly to the MAVEN project's Pom.xml file.

<dependency>        <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId></dependency>
    • 1
    • 2
    • 3
    • 4

The version of Spring boot I'm using 2.0.1.RELEASE .

Next application.properties , add the Redis configuration to the file:

spring.rabbitmq.host=127.0.0.1spring.rabbitmq.port=5672spring.rabbitmq.username=guestspring.rabbitmq.password=guest
    • 1
    • 2
    • 3
    • 4
Define ConnectionFactory and Rabbittemplate

Also very simple, the code is as follows:

Package COM.MQ.RABBITMQ;Import Org.springframework.amqp.rabbit.connection.CachingConnectionFactory;Import Org.springframework.amqp.rabbit.connection.ConnectionFactory;Import Org.springframework.amqp.rabbit.core.RabbitTemplate;Import org.springframework.boot.context.properties.ConfigurationProperties;Import Org.springframework.context.annotation.Bean;Import org.springframework.context.annotation.Configuration;@Configuration@ConfigurationProperties (prefix ="SPRING.RABBITMQ")PublicClassRabbitmqconfig {Private String host;Privateint port;Private String UserName;private String password;@BeanPublic ConnectionFactoryConnectionFactory () {Cachingconnectionfactory cachingconnectionfactory =New Cachingconnectionfactory (Host,port); Cachingconnectionfactory.setusername (UserName); Cachingconnectionfactory.setpassword (password); Cachingconnectionfactory.setvirtualhost ("www.baohuayule.com/"); Cachingconnectionfactory.setpublisherconfirms (true);return cachingconnectionfactory; }@BeanPublic rabbittemplateRabbittemplate (www.hjha178.com/) {Rabbittemplate rabbittemplate =New Rabbittemplate (ConnectionFactory ());return rabbittemplate; }Public StringGetHost (www.taohuayuan178.com) {return host; }PublicvoidSethost (String host) {This.host = host; }PublicIntGetport (www.thd178.com/) {return port; }Publicvoid setport (int port) { This.port = www.baohuayule.net port;} Public String getusername (www.leyouzaixan.cn) { return userName;} public void setusername (www.micheng178.com String userName) { this.username = userName;} Public String GetPassword () { return www.wanmeiyuele.cn password;} public void SetPassword (String password) { This.password = password;
Exchange and Queue configuration
Package COM.MQ.RABBITMQ;Import org.springframework.amqp.core.*;Import Org.springframework.context.annotation.Bean;Import org.springframework.context.annotation.Configuration;Import Java.util.HashMap;Import Java.util.Map;@ConfigurationPublicClassQueueconfig {@BeanPublic CustomexchangeDelayexchange () {map<string, object> args =New Hashmap<> (); Args.put ("X-delayed-type", "direct"); return new customexchange ( "Test_ Exchange ", true, false,args); }  @Bean public Queue queue () { Queue queue = new queue ( "Test_queue_1", true); return queue;}  @Bean public Binding binding () { return bindingbuilder.bind (Queue ()). to (Delayexchange ()). with (  "Test_queue_1"). Noargs (); 
/span>

It is important to note that the use is CustomExchange , not DirectExchange , that CustomExchange the other type must be x-delayed-message .

Implementing Message Delivery
Package COM.MQ.RABBITMQ;Import org.springframework.amqp.AmqpException;Import Org.springframework.amqp.core.Message;Import Org.springframework.amqp.core.MessagePostProcessor;Import Org.springframework.amqp.rabbit.core.RabbitTemplate;Import org.springframework.beans.factory.annotation.Autowired;Import Org.springframework.stereotype.Service;Import Java.text.SimpleDateFormat;Import Java.util.Date;@ServicePublicClassMessageserviceimpl {@AutowiredPrivate Rabbittemplate rabbittemplate;public void SENDMSG (String Queuename,string msg) {SimpleDateFormat SDF = new SimpleDateFormat (  "Yyyy-mm-dd HH:mm:ss"); System.out.println ( "message send time:" +sdf.format (new Date ())); Rabbittemplate.convertandsend ( "Test_exchange", QueueName, MSG, new messagepostprocessor () { @Override public message postprocessmessage (Message message) throws amqpexception {message.getmessageproperties (). SetHeader (  "X-delay", 3000); return message; 

Note that when sending, you must add a header

X-delay

Here I set the delay time is 3 seconds.

Message Consumers
Package COM.MQ.RABBITMQ;Import Org.springframework.amqp.rabbit.annotation.RabbitHandler;Import Org.springframework.amqp.rabbit.annotation.RabbitListener;import org.springframework.stereotype.Component; import Java.text.SimpleDateFormat; import java.util.Date;  @Component public class messagereceiver { @RabbitListener ( queues =  "test_queue_1") public  void receive (String msg) {SimpleDateFormat SDF = new SimpleDateFormat ( "Yyyy-mm-dd HH:mm:ss"); System.out.println ( "message receive time:" +sdf.format (new Date ())); System.out.println ( "received message:" +msg); 
Run the spring boot program and send messages

Run the spring boot program directly in the main method, and spring boot will parse MessageReceiver the class automatically.

Next, you only need to run the interface with JUnit to send the message.

Package COM.MQ.RABBITMQ;Import Org.junit.Test;Import Org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import Org.springframework.test.context.junit4.SpringRunner;  @RunWith (springrunner.class)  @SpringBootTest public class  rabbitmqapplicationtests { @Autowired private Messageserviceimpl Messageservice;  @Test public void send () {messageservice.sendmsg ( "Test_queue_1",                  

After running, you can see the following information:

Spring Boot RabbitMQ Deferred message implementation full version

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.