一个比较好的秒杀项目,文档来自其他大佬
- 视频中用的mybatis,个人改用的mybatis-plus
前置知识:
- 熟悉java基础知识,包括反射、泛型等
- 一些springboot基础知识
- 一些mybatis-plus或者mybatis知识
- 了解redis
- 了解mysql
- 一点点的前端基础知识(如果要完成前端部分)
- 听说过消息队列
- 如果大概了解设计模式,也许会更好,不了解也不影响
模块介绍:
- springboot-start:上手springboot所用
- login:登录模块
- seckill:秒杀模块
秒杀模块流程详解:
-
用户登录,此时涉及md5双重加密以确保安全性
- 第一次加密:客户端做,避免在http明文传输过程中被窃取
- 第二次加密:客户端做,避免被dump库后用户数据泄漏
- 两次加密都用了盐
-
用户登录后,用uuid生成token,写到cookie里面,然后查出用户的信息,以token为key,用户信息为value,写到redis缓存里面,相当于一个分布式session。
-
cookie和redis中的key的过期时间一致(都是两天)
-
用户此后的每次访问接口,都会先用cookie进行验证
- 在interceptor里面用cookie去redis查用户信息,查不到就返回提示信息;查到了就写到一个ThreaLocal里面,然后在argumentResolver中使用,方便在controller中能获得用户信息
-
里面涉及的一个点就是用户信息更新后,要更新redis中的token对应的用户信息
-
-
在秒杀的时候
-
首先是在前端加了验证码,减少用户发起请求的次数
-
其实是隐藏了真实的秒杀地址
- 要先访问一次接口获取真实的访问地址,在这个接口里面,其实就是生成了一个uuid给前端,让前端拿去拼到真实的秒杀接口里面,然后把用户id+商品id作为key,uuid做为value放到redis中
- 然后在真实的秒杀接口里面用patthvariable获取出来,进行uuid的验证,如果没有通过验证,直接返回;
- 如果通过了uuid的验证,先看内存标记,知道商品是否有剩余,再redis预减库存,(从真正的数据库)查看是否重复下单,然后把消息放到rabbitmq中
-
mq的接收端收到后,就进行真正的减库存,如果减库存成功就生成订单
-
-
前端执行秒杀后,一直轮询,查询秒杀结果
- 有订单:秒杀成功
- 没有订单,但是还有库存,排队中
- 没有订单,没有库存,秒杀失败
-
其他点:
-
自定义了注解以限定用户的访问频率,然后在interceptor中进行了检查
- 将访问的接口名与用户名作为key,次数作为value,时间做为过期时间,放到redis中
- 如果是第一次访问,就设置为1;否则就根据情况将其+1或返回相应的提示信息
-
为了方便,直接在系统启动的时候把秒杀商品的库存情况写到了本地的map中,这里是通过实现initializingBean接口来实现的,涉及到bean的生命周期
-
具体redis中的key,除了自定义的key之外,还结合了各个模块的模块名来作为真正的key
-
rabbitmq的四种模式:
- direct模式:直接把消息发给队列,只需要队列即可,不需要exchange,后面三种都需要exchange
- exchange模式:通过交换机把消息根据路由情况路由给队列
- fanout模式:广播
- headers:根据header的情况决定把消息路由给哪个队列
-
异常的全局处理:
- 自定义了一个全局的runtimeexception以及各种case的消息(包括错误码),然后在需要的地方就可以直接抛出异常
- 然后用全局的异常处理器进行捕获然后返回错误信息
-
使用了jsr303做数据校验,然后自定义了校验器做分组校验
-
使用了jmeter进行了压测,秒杀接口的pqs从700+上升到了2000+
-
使用redis时,是自己基于jedis,自定义了连接池,然后封装的工具
-