项目框架搭建:
1.SpringBoot环境搭建
2.集成thymeleaf,封装公共返回bean RespBean
3.MybatisPlus
分布式会话:
1.用户登录
a.设计数据库
b.明文密码二次MD5加密
c.参数校验+全局异常处理
2.共享Session
a.redis
功能开发:
1.商品列表
2.商品详情
3.秒杀
4.订单详情
系统压测:
1.JMeter
2.自定义变量模拟多用户
3.正式压测
a.商品列表
b.秒杀
页面优化:
1.页面缓存+对象缓存
2.页面静态化,前后端分离
秒杀服务优化:
1.redis预减库存减少数据库的访问
2.内存标记减少redis的访问
3.RabbitMQ异步下单
a.SpringBoot整合RabbitMQ
b.交换机模式
安全优化:
1.秒杀接口地址隐藏
2.算数验证码
3.接口防刷
===================
github:https://github.com/qykhhhhhhh/seckill
gitee:https://gitee.com/qyk0118/seckill
分布式session如何解决:
1.session复制,对多台tomcat服务器同步session,占用内网带宽,占用内存,同步性能也不好
2.前端存储,不安全,数据大小受cookie限制,占用外网带宽
3.后端集中存储
我们选择redis
SpringBoot如何集成redis:
配置依赖,配置yml
配置redis序列化问题
具体如何实现:
doLogin登录成功时存 key=uuid value=用户对象 到redis中,并在设置cookie为保存uuid(key=uuid,value=uuid值)
页面缓存:
将html页面缓存到redis里,每次从redis中取页面,取得到直接返回页面,取不到要手动渲染并且存到redis中
页面静态化:
页面静态化,ajax动态载入数据,替代了redis缓存页面
RabbitMQ:
生产者的消息都是发给交换机的,不同交换机有不同模式
fanout模式:给绑定了该交换机的队列发消息
direct模式:队列绑定交换机时会关联路由键,当生产者生成消息时可以指定路由键,交换机把消息传到指定路由键的队列
topic模式:direct模式+模糊匹配
RabbitMQ集成springboot
1.添加依赖
2.配置yaml
3.config类配置队列
4.发送者 接收者
秒杀功能:
服务器启动,redis存库存数量(1),开始秒杀,进行重复抢购判断(redis)(粗过滤)
redis进行预减库存(2),当库存抢完时,做一个标记(3),后续秒杀请求进来时就不用进入redis查询了,直接根据这个标记判断,减少redis访问
如果抢到了,把秒杀信息放入RabbitMQ,RabbitMQ很好地进行了削峰,RabbitMQ队列内对每个秒杀请求进行重复抢购判断(redis)(细过滤),如果没问题进入service层进行下单
进行库存判断和库存更新,因为加了事务所以判断和更新具有原子性,如果没库存就直接返回,否则开始生成订单保存到数据库中,数据库使用了索引,所以数据库从表锁变成行锁,并发程度更好
ps: 重复抢购:redis存订单信息,订单信息中包含用户id和商品id,如果两个都匹配,则为重复抢购
ps: 预减库存:decrement方法先减,具有原子性,然后判断redis中库存是否小于0,如果小于0再加回去并设置内存标记,同样是粗过滤,因为先减和判断不具备原子性
秒杀地址隐藏:
秒杀地址隐藏,前端点击秒杀时后端先进行生成与用户id和商品id关联的随机秒杀地址路径,存在redis里,然后将路径传到前端,前端再通过这个路径进行秒杀,后端接收到该路径,对redis查询,如果没有该路径,则无法秒杀
验证码:
验证码,前端刷新一次验证码,都会从后端获取验证码图片,并且后端会把验证码答案存入redis,当客户输入验证码后,答案回到后端进行判断,如果对了则秒杀,错了则提示
接口防刷:
redis实现计数器:redis中存秒杀接口和用户id相关联的key,value是访问次数count,设置他的存活时间很短,每次点击秒杀都会让count+1,当count大于一定值后就会直接抛出访问频繁的提示,以此来接口防刷