Recently, there is such a scene in the business that if users place an order in the mall and do not pay within 30 minutes, they need to process the order, either delete it directly or mark it as invalid. Why do they do this?
- 1. Inventory: After placing an order, the user will lock an inventory. If the user does not pay all the time, the inventory will be occupied and other users will be affected to buy.
- 2. With the development of business and the increase of users, our order data will be more and more, so we need to timely clean up invalid orders and improve the performance of the system;
Once pure
First of all, I had a pure idea. When I first saw this demand, if I wanted to clear invalid orders, I would write a regular task and run every 5 or 10 minutes to delete overdue orders and increase inventory.
Timed tasks can indeed solve the above problems, but there is a real problem, that is database pressure, and even affect the performance of the entire system, if you are hundreds or thousands of orders ok, if you are tens of thousands, or even millions, then this method will not work.
The advanced version
Since found the method above can’t, so just to think of some way to, what method can not query the database, you can know which order is overdue, then such thinking, I use the Redis for a message queue, when making orders, generate a delay for 10 minutes, 10 minutes at the end of the, I pull the order out of the Redis queue, and then I can delete the order and increase inventory.
Problems with Redis doing message queues
Before using a new Redis to do message queue, the storage data is not much, it feels good, when the business increases, Redis storage exceeds 90%, a large number of messages are not consumed, that is, the message loss is very serious. So this is definitely not going to work.
Delete orders, increase inventory this is not a matter of too much error, so THE Redis message queue can not meet my needs, so I need a reliable message queue, which we will introduce RabbitMQ this time.
RabbitMQ installation and panel introduction
I won’t tell you how to install RabbitMQ, there are many tutorials on the web, so do your own research. It is important to note that the RabbitMQ panel, our message queue, and messages are all visible on the panel. I am using version 3.8 of MQ, and the panels may be somewhat different from version to version.
For the first time, let’s not try to think that I can understand everything at once, I know what it is, I don’t think it’s necessary, but let’s get familiar with the basics, I’ve circled two places above: Queue, Admin, and Add a new Queue. These are the three basic things that we need to learn.
- Queue: This is the message Queue we declared;
- Admin: User management, RabbitMQ has a guest user by default, but the magic of RabbitMQ is that each library must create a user role;
- Add a new queue: This is to create a new queue, but we don’t do this directly, we do it in code;
If you want to declare a queue, you must have a library. Queues exist in a library. If you want to declare a queue, you must have a library. The same is true for MQ.
The Virtual Hosts on the right is to create the library. Name is the Name of the library.
If you are careful, you can see that the two queues in the first picture are preceded by the library name, indicating that the queue exists in the xiaoshuo library.
A simple message queue
When the producer produces a message and sends it to the queue, the consumer listens to the message in the queue for consumption, so we will implement a simple message queue first.
code
We’re not going to use the SpringBoot framework, so we’re going to start with a basic, life-native API so we can understand what’s going on later.
1. Import the required POM files
<dependency> <groupId>com.rabbitmq</groupId> <artifactId>amqp-client</artifactId> <version>4.0.2</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.10</version> </dependency> Slf4j </groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.5</version> </dependency> <dependency> <groupId>log4j</groupId>
<artifactId>log4j</artifactId <version>1.2.17</version> </dependency> <dependency> <groupId>junit</groupId> < artifactId > junit < / artifactId > < version > 4.11 < / version > < / dependency >Copy the code
2. Connect to RabbitMQ
/** * @description: TODO MQ connection factory * @author: bingfeng * @create: 2020-05-07 08:55 */ public class MQConnectUtil { public static Connection getConnection() throws IOException, TimeoutException {// define the ConnectionFactory ConnectionFactory factory = new ConnectionFactory(); // Set the connection address factory.sethost ("127.0.0.1"); // setPort factory.setport (5672); // Select vhost factory.setVirtualHost("/xiaoshuo"); // set the user name factory.setusername ("bingfeng"); / / password factory. SetPassword ("123");
returnfactory.newConnection(); }}Copy the code
3. Send a message
/** * @description: TODO analog send message * @author: bingfeng * @create: 2020-05-07 09:01 */ public class Producer {/** * public static final String QUEUE_NAME ="simple_queue_test"; public static void main(String[] args) throws IOException, TimeoutException { Connection connection = MQConnectUtil.getConnection(); // Get a Channel from the connection Channel Channel = connection.createchannel (); Channel. queueDeclare(QUEUE_NAME,false.false.false, null); // Message content String MSG ="Hello, Bingfeng!;
channel.basicPublish("", QUEUE_NAME, null, msg.getBytes());
System.out.println("Send a message:"+ msg); channel.close(); connection.close(); }}Copy the code
4. Consumer news
/** * @description: TODO consumption MQ * @author: bingfeng * @create: 2020-05-07 09:11 */ public class Consumer { public static final String QUEUE_NAME ="simple_queue_test"; Public static void main (String [] args) throws the Exception {/ / to get connected Connection Connection. = MQConnectUtil getConnection (); // createChannel Channel = connection.createchannel (); Channel. queueDeclare(QUEUE_NAME,false.false.false, null); Consumer = new DefaultConsumer(channel) {@override public void handleDelivery(String) consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) { String msg = new String(body, StandardCharsets.UTF_8); System.out.println("Consumer News:+ msg); }}; // Listen to queue channel.basicConsume(QUEUE_NAME,true, consumer); }}Copy the code
After we send a message, we can see the number of messages in the queue directly in the panel
After clicking in, pull to the below, Messages is the number of Messages we want to view, that is, how many Messages you want to see and fill in the number, after filling in, click the following Get Messages, our recent Messages will be displayed below.
When we consume the message, it is no longer in the queue.
The last word
Wrote this, today I’m going to put the RabbitMQ from entry to all the project practical usage of the cascaded Shared with everybody, one is to prevent his forget you can come back after check out, 2 it is to share with everyone interested friends can learn together, I will be back I said before, the order date to delete business scenario would write it again.
For those of you who are familiar with RabbitMQ, it may seem easy to solve the problem, but there are many people who have never used MQ in their actual work and may not know about it themselves, so for those of you who haven’t, I think it’s a good idea to get in.
If you have any questions, welcome to solo.
Recently, there is such a scene in the business that if users place an order in the mall and do not pay within 30 minutes, they need to process the order, either delete it directly or mark it as invalid. Why do they do this?
- 1. Inventory: After placing an order, the user will lock an inventory. If the user does not pay all the time, the inventory will be occupied and other users will be affected to buy.
- 2. With the development of business and the increase of users, our order data will be more and more, so we need to timely clean up invalid orders and improve the performance of the system;
Once pure
First of all, I had a pure idea. When I first saw this demand, if I wanted to clear invalid orders, I would write a regular task and run every 5 or 10 minutes to delete overdue orders and increase inventory.
Timed tasks can indeed solve the above problems, but there is a real problem, that is database pressure, and even affect the performance of the entire system, if you are hundreds or thousands of orders ok, if you are tens of thousands, or even millions, then this method will not work.
The advanced version
Since found the method above can’t, so just to think of some way to, what method can not query the database, you can know which order is overdue, then such thinking, I use the Redis for a message queue, when making orders, generate a delay for 10 minutes, 10 minutes at the end of the, I pull the order out of the Redis queue, and then I can delete the order and increase inventory.
Problems with Redis doing message queues
Before using a new Redis to do message queue, the storage data is not much, it feels good, when the business increases, Redis storage exceeds 90%, a large number of messages are not consumed, that is, the message loss is very serious. So this is definitely not going to work.
Delete orders, increase inventory this is not a matter of too much error, so THE Redis message queue can not meet my needs, so I need a reliable message queue, which we will introduce RabbitMQ this time.
RabbitMQ installation and panel introduction
I won’t tell you how to install RabbitMQ, there are many tutorials on the web, so do your own research. It is important to note that the RabbitMQ panel, our message queue, and messages are all visible on the panel. I am using version 3.8 of MQ, and the panels may be somewhat different from version to version.
For the first time, let’s not try to think that I can understand everything at once, I know what it is, I don’t think it’s necessary, but let’s get familiar with the basics, I’ve circled two places above: Queue, Admin, and Add a new Queue. These are the three basic things that we need to learn.
- Queue: This is the message Queue we declared;
- Admin: User management, RabbitMQ has a guest user by default, but the magic of RabbitMQ is that each library must create a user role;
- Add a new queue: This is to create a new queue, but we don’t do this directly, we do it in code;
If you want to declare a queue, you must have a library. Queues exist in a library. If you want to declare a queue, you must have a library. The same is true for MQ.
The Virtual Hosts on the right is to create the library. Name is the Name of the library.
If you are careful, you can see that the two queues in the first picture are preceded by the library name, indicating that the queue exists in the xiaoshuo library.
A simple message queue
When the producer produces a message and sends it to the queue, the consumer listens to the message in the queue for consumption, so we will implement a simple message queue first.
code
We’re not going to use the SpringBoot framework, so we’re going to start with a basic, life-native API so we can understand what’s going on later.
1. Import the required POM files
<dependency> <groupId>com.rabbitmq</groupId> <artifactId>amqp-client</artifactId> <version>4.0.2</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.10</version> </dependency> Slf4j </groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.5</version> </dependency> <dependency> <groupId>log4j</groupId>
<artifactId>log4j</artifactId <version>1.2.17</version> </dependency> <dependency> <groupId>junit</groupId> < artifactId > junit < / artifactId > < version > 4.11 < / version > < / dependency >Copy the code
2. Connect to RabbitMQ
/** * @description: TODO MQ connection factory * @author: bingfeng * @create: 2020-05-07 08:55 */ public class MQConnectUtil { public static Connection getConnection() throws IOException, TimeoutException {// define the ConnectionFactory ConnectionFactory factory = new ConnectionFactory(); // Set the connection address factory.sethost ("127.0.0.1"); // setPort factory.setport (5672); // Select vhost factory.setVirtualHost("/xiaoshuo"); // set the user name factory.setusername ("bingfeng"); / / password factory. SetPassword ("123");
returnfactory.newConnection(); }}Copy the code
3. Send a message
/** * @description: TODO analog send message * @author: bingfeng * @create: 2020-05-07 09:01 */ public class Producer {/** * public static final String QUEUE_NAME ="simple_queue_test"; public static void main(String[] args) throws IOException, TimeoutException { Connection connection = MQConnectUtil.getConnection(); // Get a Channel from the connection Channel Channel = connection.createchannel (); Channel. queueDeclare(QUEUE_NAME,false.false.false, null); // Message content String MSG ="Hello, Bingfeng!;
channel.basicPublish("", QUEUE_NAME, null, msg.getBytes());
System.out.println("Send a message:"+ msg); channel.close(); connection.close(); }}Copy the code
4. Consumer news
/** * @description: TODO consumption MQ * @author: bingfeng * @create: 2020-05-07 09:11 */ public class Consumer { public static final String QUEUE_NAME ="simple_queue_test"; Public static void main (String [] args) throws the Exception {/ / to get connected Connection Connection. = MQConnectUtil getConnection (); // createChannel Channel = connection.createchannel (); Channel. queueDeclare(QUEUE_NAME,false.false.false, null); Consumer = new DefaultConsumer(channel) {@override public void handleDelivery(String) consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) { String msg = new String(body, StandardCharsets.UTF_8); System.out.println("Consumer News:+ msg); }}; // Listen to queue channel.basicConsume(QUEUE_NAME,true, consumer); }}Copy the code
After we send a message, we can see the number of messages in the queue directly in the panel
After clicking in, pull to the below, Messages is the number of Messages we want to view, that is, how many Messages you want to see and fill in the number, after filling in, click the following Get Messages, our recent Messages will be displayed below.
When we consume the message, it is no longer in the queue.
The last word
Wrote this, today I’m going to put the RabbitMQ from entry to all the project practical usage of the cascaded Shared with everybody, one is to prevent his forget you can come back after check out, 2 it is to share with everyone interested friends can learn together, I will be back I said before, the order date to delete business scenario would write it again.
For those of you who are familiar with RabbitMQ, it may seem easy to solve the problem, but there are many people who have never used MQ in their actual work and may not know about it themselves, so for those of you who haven’t, I think it’s a good idea to get in.
If you have any questions, welcome to solo.