Java高性能高并发秒杀系统(10)

1. 库存预加载到Redis中是怎么实现的?

我是通过实现InitializingBean接口,重写其中afterPropertiesSet()方法,实现的预加载

1.1 之后主动添加秒杀商品的话,怎么添加?

通过后台管理进行添加,修改redis缓存和数据库中的值


Java高性能高并发秒杀系统(9)

1. 动态秒杀地址

1.1 前端的改变

之前我们实现秒杀的时候是直接跳转到秒杀接口,使得我们每次的秒杀地址都是一样的,这样具有安全隐患,所以,我们将其改为动态地址,通过在前端上写一个方法进行跳转,如下所示。

  • 它会先跳转到/miaosha/path,获取秒杀地址中的path值,将其存储在Redis中在这里插入图片描述
  • 然后携带path值去访问真正的秒杀方法,在其中将path值与Redis中的值进行比较,一致才能继续秒杀
    在这里插入图片描述

1.2 获取路径的Java代码

Java高性能高并发秒杀系统(8)

1. 秒杀接口优化思路

重点我们是要减少对数据库的访问

  1. 系统初始化时,将秒杀商品库存加载到Redis中
  2. 收到请求,在Redis中预减库存,库存不足时,直接返回秒杀失败
  3. 秒杀成功,将订单压入消息队列,返回前端消息“排队中”(像12306的买票)
  4. 消息出队,生成订单,减少库存
  5. 客户端在以上过程执行过程中,将一直轮询是否秒杀成功

2. 清晰框图解析

Java高性能高并发秒杀系统(7)

1. 集成RabbitMQ

1.1 添加依赖

在这里插入图片描述
在这里插入图片描述

1.2 添加配置信息

在这里插入图片描述
在这里插入图片描述

Java高性能高并发秒杀系统(6)

1. 页面缓存优化

1.1 未经优化之前的代码

    @RequestMapping("/to_list")
    public String toList(Model model,MiaoShaUser user){
        model.addAttribute("user",user);
        List<GoodsVo> goodsVos = goodsService.listGoodsVo();
        model.addAttribute("goodsList",goodsVos);
        return "goods_list";
    }
1234567

1.2 优化产生的改变

在这里插入图片描述
在这里插入图片描述

Java高性能高并发秒杀系统(5)

1. JMeter压力测试

1.1 测试过程

  1. 打开jmeter.bat
    在这里插入图片描述
  2. 设置HTTP默认请求
    在这里插入图片描述
    编写协议和端口号
    在这里插入图片描述
  3. 编写测试HTTP请求
    在这里插入图片描述
    因为我们已经写过默认设置,我们就可以不用编写协议和地址了,如下,只需编写请求类型地址即可
    在这里插入图片描述
  4. 添加聚合报告

我们即可在报告中查看压测信息
在这里插入图片描述

1.2 Linux top命令

Java高性能高并发秒杀系统(4)

1. 实现联表查询的一个小技巧

在这里插入图片描述
商品表和秒杀商品表是两个互相独立的表,其中的关联为goods_id,但是我要返回的对象,既想要商品表中的字段,又想要秒杀商品表中的字段,用下面这个方法,有点儿亮眼

@Data
public class GoodsVo extends Goods {
    private Double miaoshaPrice;
    private Integer stockCount;
    private Date startDate;
    private Date endDate;
}
1234567

创建一个GoodsVo类,继承Goods类,再将秒杀商品表中特有的字段,添加进去即可

1.1 左联表查询SQL语句

Java高性能高并发秒杀系统(3)

1. 实现分布式Session

1.1 原理图解

在这里插入图片描述
在这里插入图片描述
  • 作用:用Redis存储Session值,在Redis中通过token值来获取用户信息

1.2 每次登陆,将Session的过期时间进行修正

Java高性能高并发秒杀系统(2)

1. 登录过程中,密码两次MD5加密

1.1 为啥用两次MD5哇?

  1. 第一次MD5,是针对传输安全做的MD5加密,因为http是明文传递,如果不进行加密的话,密码就直接被劫持了。
    (Password1 = MD5(inputPassword,固定的salt值),salt为字符串)
  2. 第二次MD5,是针对数据库安全做的MD5加密,保证数据库的防盗安全。若不进行二次加密,MD5值经数据库获取,可直接被MD5转换器直接转换为用户密码,不安全。
    (Password2 = MD5(Password1,随机的salt值))

2. 构建数据库表

Java高性能高并发秒杀系统

@CSDN方 圆

1. 集成Mybatis

我觉得在集成Mybatis时问题并不大

1.1 新接触的不用xml文件写Mapper文件

@Mapper
@Component
public interface UserMapper {

    @Select("select * from user where id = #{id}")
    User selectById(@Param("id") int id);

    @Insert("insert into user (id,name) values (#{id},#{name})")
    int insertUser(User user);
}