## 页面优化 为没优化时qps翻一倍
提高响应速率,减去不必要的渲染处理。
### 页面缓存进redis
每次都是请求thymeleaf渲染
可以用缓存,存进整个页面 从redis中取页面
### 页面静态化 前后端分离就是页面静态化
虽然进行了页面静态化,但是还是传输整个页面数据量大。
用静态化,静态页面浏览器缓存好了,只需要ajax传输数据,controller层不再用String跳转页面,变为返回对象,减少传输量
## 库存超卖,超买
**超卖**:在高并发的情况下,可能发生超卖问题,在判断库存是否为0和减库存不原子性操作,使用mp的wrapper的sql进行减库存,用gt进行判断库存>0,原子性操作解决超卖问题
**超买**:在高并发的情况下,可能一个用户同时发送多个请求,同时判断为没有买过,超买问题出现。
下单成功,把用户id 商品id为key,商品信息为value存进redis,下次购买时,Redis获取看是否为null,不是的话就是买过了,减少数据库的访问量
在数据库的订单加唯一索引(用户id+商品id)解决超买
## 服务优化 {redis预减库存,redis内存标记,rabbitmq异步下单} 为没优化时3倍qps
都是为了减少数据库的访问,以至于对redis的访问。
减少大量的访问从而减少了服务的处理时间从而加大了响应效率加大了用户的使用体验。
### 预减库存
在初始化时,把商品库存存进redis,请求来时,先减少redis的库存,当库存为0之后,不需要在请求数据库,直接返回结果
如果可秒杀通过rabbitmq进行异步下单{和之前不用redis预减库存一样},预减库存只是为了库位为0时不再访问数据库。
### 内存标记
在预减库存之后,虽然大程度的减少了对数据库的访问,但是还是存在大量访问redis的情况,所以初始化时使用map<商品id,true or false>,
在redis预减库存之前判断商品库存是否为0,如果为空那就不再进行访问redis预减库存,直接返回结果。
### rabbitmq异步下单
通过rabbitmq异步下单可提升用户体验,不需要等待所有的处理流程,只需要等待rabbitmq异步处理返回的下单结果,此通过判断
订单库中是否有 该用户购买的该商品 如果有 返回1{下单成功}
如果没有,查询redis中是否有该商品的“空库存”key值{这里在下单时的防止超卖的判断后判断此时的库存是否为0,如果为0,在redis加上该商品的“空库存”key值} 有的话就是库存为0了,返回-1{下单失败}
如果不是上面两种情况 那就说明rabbitmq异步下单操作还没完成,页面轮训查询。
## 安全优化 {秒杀地址隐藏,验证码}
### 秒杀地址隐藏
对真正的秒杀地址做隐藏,通过点击秒杀按钮生成随机数拼接的到真正的秒杀地址。防止黄牛提前得到真正的秒杀地址,在秒杀开始之前秒杀完商品,
防脚本疯狂访问真正的秒杀地址,而是通过点击秒杀按钮获得真正的秒杀地址进行秒杀。
### 验证码
防止脚本疯狂秒杀,因为需要计算验证码。
拉长短时间内的访问量减少负荷。
### 接口限流{redis计数器}
防止大量请求突破qps承受量,通常设置为qps的70%-80%
进行接口限流通过redis
可通过请求uri+user.id作为key,次数作为value的方式,加上存活时间 比如5秒最多5个请求,存活时间就是5,通过这个方式加入redis做计数器
第一次请求时set上,加上value为1
不是第一次 且value小于5时,使用increment原子性自增1
大于等于5 抛异常