Springclub09 rabbitmq pinduo mall integration

Time:2021-1-9

Pinduo mall integrates rabbitmq

When a user places an order, our business system directly communicates with the database and saves the order to the database. When the system traffic suddenly surges, a lot of order pressure will slow down the business system and the database system
We need to deal with the peak traffic and make the traffic curve smooth, as shown in the figure below
Springclub09 rabbitmq pinduo mall integration

1. Decoupling of order storage

In order to reduce the traffic peak, we introduce rabbitmq message queue. When the shopping system generates an order, it can send the order data to the message queue. The order consumer application receives the order message from the message queue and saves the order to the database
Springclub09 rabbitmq pinduo mall integration
In this way, when the traffic surge, a large number of orders will be temporarily stored in rabbitmq, and order consumers can calmly receive orders from the message queue and save them to the database

2. Create pdweb project

Just import the project from the pre class materials
Springclub09 rabbitmq pinduo mall integration

3. Define producer – send order

three point one pom.xml Add dependency

Spring provides a more convenient message queue access interface, which encapsulates the client API of rabbitmq and makes it more convenient to use

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

3.2 modification application.yml file

Add connection information for rabbitmq

spring:
  rabbitmq:
    host: 192.168.64.140
    port: 5672
    virtualHost: /pd
    username: admin
    password: admin 

3.3 modify the main program runpdapp

Add the following method to the main program to create a queue instance
After creating a rabbitmq connection and channel, spring’s rabbitmq tool will automatically create a queue in the server, and the code will be displayed in theRabbitAdmin.declareQueues()In the method

 @Bean
    public Queue getQueue() {
        Queue q = new Queue("orderQueue", true);
        return q;
    }

3.4 modify orderserviceimpl

//An ampqtemplate instance is created in rabbit autoconfiguration
    @Autowired
    AmqpTemplate amqpTemplate;
    //The original database access code of saveorder is annotated, and the rabbitmq message sending code is added
    public String saveOrder(PdOrder pdOrder) throws Exception {
        String orderId = generateId();
        pdOrder.setOrderId(orderId);

        amqpTemplate.convertAndSend("orderQueue", pdOrder);
        return orderId;

        
        //        String orderId = generateId();
        //        pdOrder.setOrderId(orderId);
        //
        // 
        //        PdShipping pdShipping = pdShippingMapper.selectByPrimaryKey(pdOrder.getAddId());
        //        pdOrder.setShippingName(pdShipping.getReceiverName());
        //        pdOrder.setShippingCode(pdShipping.getReceiverAddress());
        //        pdOrder.setStatus(1);// 
        //        pdOrder.setPaymentType(1);
        //        pdOrder.setPostFee(10D);
        //        pdOrder.setCreateTime(new Date());
        //
        //        double payment = 0;
        //        List<ItemVO> itemVOs = selectCartItemByUseridAndItemIds(pdOrder.getUserId(), pdOrder.getItemIdList());
        //        for (ItemVO itemVO : itemVOs) {
        //            PdOrderItem pdOrderItem = new PdOrderItem();
        //            String id = generateId();
        //            //String id="2";
        //            pdOrderItem.setId(id);
        //            pdOrderItem.setOrderId(orderId);
        //            pdOrderItem.setItemId("" + itemVO.getPdItem().getId());
        //            pdOrderItem.setTitle(itemVO.getPdItem().getTitle());
        //            pdOrderItem.setPrice(itemVO.getPdItem().getPrice());
        //            pdOrderItem.setNum(itemVO.getPdCartItem().getNum());
        //
        //            payment = payment + itemVO.getPdCartItem().getNum() * itemVO.getPdItem().getPrice();
        //            pdOrderItemMapper.insert(pdOrderItem);
        //        }
        //        pdOrder.setPayment(payment);
        //        pdOrderMapper.insert(pdOrder);
        //        return orderId;
    }

4. Consumer – receive the order and save it to the database

4.1 copy PD web project as PD order consumer

Springclub09 rabbitmq pinduo mall integration

4.2 modification application.yml file

Change the port to 81

server:
  port: 81

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/pd_store?useUnicode=true&characterEncoding=utf8
    username: root
    password: root

  rabbitmq:
    host: 192.168.64.140
    port: 5672
    virtualHost: /pd
    username: admin
    password: admin

mybatis:
  #typeAliasesPackage: cn.tedu.ssm.pojo
  mapperLocations: classpath:com.pd.mapper/*.xml

logging:
  level: 
    cn.tedu.ssm.mapper: debug

4.3 new orderconsumer

package com.pd;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.pd.pojo.PdOrder;
import com.pd.service.OrderService;
@Component
public class OrderConsumer {
    //After receiving the order data, the business code of the order will be called to save the order to the database
    @Autowired
    private OrderService orderService;

    //After the annotation is added, the message is received from the specified orderqueue,
    //The data is transformed into a pdorder instance and passed to this method
    @RabbitListener(queues="orderQueue")
    public void save(PdOrder pdOrder)
    {
        System.out.println (the "consumer");
        System.out.println(pdOrder.toString());
        try {
            orderService.saveOrder(pdOrder);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

4.4 modify the saveorder() method of orderserviceimpl

public String saveOrder(PdOrder pdOrder) throws Exception {
        //        String orderId = generateId();
        //        pdOrder.setOrderId(orderId);
        //
        //        amqpTemplate.convertAndSend("orderQueue", pdOrder);
        //        return orderId;
        //
        // 
        // 
        //        String orderId = generateId();
        //        pdOrder.setOrderId(orderId);
        
        //Order data received from rabbitmq,
        //The ID has been generated in the upstream order business. Here, the ID will not be generated again
        //Get the ID of the order directly
        String orderId = pdOrder.getOrderId();

        
        PdShipping pdShipping = pdShippingMapper.selectByPrimaryKey(pdOrder.getAddId());
        pdOrder.setShippingName(pdShipping.getReceiverName());
        pdOrder.setShippingCode(pdShipping.getReceiverAddress());
        pdOrder.setStatus(1);// 
        pdOrder.setPaymentType(1);
        pdOrder.setPostFee(10D);
        pdOrder.setCreateTime(new Date());

        double payment = 0;
        List<ItemVO> itemVOs = selectCartItemByUseridAndItemIds(pdOrder.getUserId(), pdOrder.getItemIdList());
        for (ItemVO itemVO : itemVOs) {
            PdOrderItem pdOrderItem = new PdOrderItem();
            String id = generateId();
            //String id="2";
            pdOrderItem.setId(id);
            pdOrderItem.setOrderId(orderId);
            pdOrderItem.setItemId("" + itemVO.getPdItem().getId());
            pdOrderItem.setTitle(itemVO.getPdItem().getTitle());
            pdOrderItem.setPrice(itemVO.getPdItem().getPrice());
            pdOrderItem.setNum(itemVO.getPdCartItem().getNum());

            payment = payment + itemVO.getPdCartItem().getNum() * itemVO.getPdItem().getPrice();
            pdOrderItemMapper.insert(pdOrderItem);
        }
        pdOrder.setPayment(payment);
        pdOrderMapper.insert(pdOrder);
        return orderId;
    }

5. Manual confirmation

5.1 modification application.yml file

spring:
  rabbitmq:
    listener:
      simple:
        acknowledge-mode: manual` 

5.2 OrderConsumer

package com.pd;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.pd.pojo.PdOrder;
import com.pd.service.OrderService;
import com.rabbitmq.client.Channel;
@Component
public class OrderConsumer {
    //After receiving the order data, the business code of the order will be called to save the order to the database
    @Autowired
    private OrderService orderService;

    //After the annotation is added, the message is received from the specified orderqueue,
    //The data is transformed into a pdorder instance and passed to this method
    @RabbitListener(queues="orderQueue")
    public void save(PdOrder pdOrder, Channel channel, Message message)
    {
        System.out.println (the "consumer");
        System.out.println(pdOrder.toString());
        try {
            orderService.saveOrder(pdOrder);
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            e.printStackTrace();
        } 
    }
}