2.5 订单流量削峰案例



1.概述

假设我们向商城的订单系统下订单,在短时间内突然产生大量订单的情况下,直接向数据库存储数据可能会导致数据库崩溃;

但是如果我们使用RabbitMQ消息服务进行接收的话,订单会在RabbitMQ处进行排队等待消费者进行处理,一个一个的接收进行处理然后存储到数据库中,避免因突增的大量访问数据而导致系统崩溃;

这就是流量削峰,将短时间内突增的大量数据访问造成的流量峰值处理时间进行拉长,消除其流量峰值;

RabbitMQ数据吞吐量是非常大的,可以轻松承担数据库无法承担的压力,当RabbitMQ也无法承担压力时,可以选择增加服务器,或使用阿里,腾讯的RabbitMQ,腾讯的RabbitMQ号称可以承担万亿级别的流量;

当大量数据排队时,可能会导致处理时间过长的问题,此时可以增加消费者来进行数据的多线程处理;

2.项目准备

2.1 导入项目

找i到gitee仓库cheapter-six项目中file文件夹中的pd-web项目压缩文件,拉取到本地后解压到rabbitmq目录下:
在这里插入图片描述

在文件夹中直接将pom.xml文件拖拽到IDEA编辑区域中,修改springboot版本为2.3.2.RELEASE;

编辑完成后,直接在编辑区域右键–Add Maven Project以maven方式导入此工程:
在这里插入图片描述

2.2 导入数据库

在SQLYog左侧地址栏空白处右键,选择从SQL转储文件导入数据库,选择pd-web目录下的pd.sql文件进行导入:
在这里插入图片描述

如果导入失败可能是因为数据库缓存不够引起的,可以增大数据库缓存后重新执行;导入完成后,检查表中是否存在测试数据,删除所有测试数据:

# 删除用户数据
delete from pd_user

# 删除订单数据
delete from pd_order
delete from pd_order_item

2.3启动项目

  1. 右键点击RunApp,运行项目
  2. 在启动配置中,配置working directory,设置称pd-web文件夹的路径
  3. 重启RunApp
  4. 访问http://localhost,如果看到浏览器在下载需要清理浏览器缓存后重新访问;

在这里插入图片描述

在这里插入图片描述

2.4 测试项目基础功能

  1. 测试用户注册
    在这里插入图片描述

在这里插入图片描述

  1. 添加收货地址
    在这里插入图片描述

注意除必填项外,其他内容需保证填写正确,项目为测试项目,缺少许多校验程序,填写错误也可以添加成功,但会影响后续功能;

  1. 创建订单
    点击商品后,将其加入购物车,在购物车中选中商品点击去结算,在确认订单页面点击确认并付款,此时我们的订单就已经创建好了:
    在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

此时保存在数据库中的订单就是一个未付款的订单;

2.5 数据库操作代码注释

我们将项目中,订单数据库操作的相关代码全部注释,使用RabbitMQ进行数据的处理:
在这里插入图片描述

3.订单发送到RabbitMQ

我们对项目进行改造,使订单不执行数据库操作,而是通过RabbitMQ进行存储:
在这里插入图片描述

3.1 依赖添加

在pom.xml文件中添加RabbitMQ依赖:

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

3.2 配置文件添加连接配置

在application.yml配置文件中添加连接配置:

  rabbitmq:
    host: 192.168.64.140
    port: 5672
    username: admin
    password: admin

3.3 代码实现

3.3.1 队列参数实现

因为启动类本身就是一个自动配置类,所以我们直接在启动类中(或者自定义自动配置类)配置队列参数:

  1. 因为订单是不允许丢失的,所以我们使用持久队列
  2. 为了考虑订单的处理效率,所以设置非独占队列
  3. 因为订单的不可丢失特性,所以我们设置队列不可自动删除
	//创建对象,封装队列使用的参数,配置使用的队列
	//orderQueue:持久,非独占,不自动删除
	@Bean
	public Queue orderQueue(){
		return new Queue("orderQueue",true,false,false);
	}

注意这里使用的Queue对象是spring封装的Queue对象,不是原生的RabbitMQ的Queue对象;

3.3.2 订单处理方法实现

我们注入AmqpTemplate工具:

	@Autowired
	private AmqpTemplate amqpTemplate;

使用AmqpTemplate封装工具发送订单即可:

		/**
		 * 使用AmqpTemplate对象实现消息发送
		 * 将订单转换为byte数组并发送到orderQueue
		 * 订单实例会自动被序列化成 byte[] 数组再进行转发
		 * PdOrder已实现序列化接口
		 * */
		amqpTemplate.convertAndSend("orderQueue",pdOrder);

3.4 订单发送测试

重新启动项目后,创建新的订单:
在这里插入图片描述

订单创建完成后,此时数据库中并没用我们新的订单数据,订单数据被存储到了RabbitMQ队列中,我们在RabbitMQ控制台的队列中点击我们刚创建的队列:
在这里插入图片描述

进入队列后,在队列中点击getMessage即可查看订单消息:
在这里插入图片描述

因为序列化的原因,数据显示是byte类型的字节码值,不是按照字符类型显示的,所以我们无法直接查看;

4.消费者执行数据库操作

4.1 项目准备

我们在文件夹中,将pd-web文件夹复制一份并命名为pd-web-consumer
在这里插入图片描述

将pd-web-consumer文件夹中的pom.xml文件拖拽到IDEA中修改artifactId为当前文件夹名称:
在这里插入图片描述

修改完成后,在当前界面空白处右键选择 Add as Maven Projecte 进行导入:
在这里插入图片描述

修改项目的端口为81:
在这里插入图片描述

我们复制的项目中,已经对RabbitMQ的依赖,连接配置,使用的队列等进行了配置,复制后直接使用即可;

4.2 订单消费者创建

4.2.1 新建消费者类

我们获取队列中的消息,调用接口实现类保存订单:

  • 通过注解配置,从orderQueue 接收订单;
  • 调用OrderServiceImpl.saveOrder()存储订单;
package com.pd;

import com.pd.pojo.PdOrder;
import com.pd.service.OrderService;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
@RabbitListener(queues = "orderQueue")  //通过注解配置从orderQueue接收订单消息
public class OrderConsumer {

    @Autowired
    private OrderService orderService;
    /**
     * 自定义处理消息的方法
     * 传入参数为接收队列中的参数
     * @RabbitHandler注解配合RabbitListener用来指定处理消息的方法
     * 一个类中只能有一个@RabbitHandler注解描述的方法
     * */
    @RabbitHandler
    public void recive(PdOrder order) throws Exception {
        orderService.saveOrder(order);
        System.out.println("订单已保存!!");
    }

}

4.2.2 调整OrderServiceImpl

因为我们是复制的项目,数据库操作代码此前已经被注释,这里我们需要打开注释代码,并且注释注入的AmqpTemplate实例;因为我们在前边的操作已经生成了orderId,所以这里要将生成orderId的代码也注释掉并且将此前生成的orderId获取到:
在这里插入图片描述

4.3 测试

我们启动项目进行测试,在项目启动时,我们就可以看到控制台打印的订单保存信息:
需要同时启动生产者和消费者,并且生产者要正常创建队列;
在这里插入图片描述

并且在数据库中我们也可以看到记录数据的存储;

5.总结

类似于这种商城的订单系统,将直接发送到数据库的订单信息先发送到RabbitMQ,然后再排队慢慢处理,可以有效的解决流量突增的情况,这里一般使用简单模式或工作模式;

我们使用封装的AmqpTemplate封装工具转换并发送消息,使用@RabbitListener注解进行消息的接收;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值