欢迎光临散文网 会员登陆 & 注册

优极限【完整项目实战】半天带你用-springBoot、Redis轻松实现Jav

2023-04-01 20:05 作者:仲夏七月梦  | 我要投稿

秒杀功能设计:

  • 秒杀起止时间与动态倒计时、商品原价与秒杀价、商品秒杀库存、“秒杀”按钮的置灰与秒杀进行中的设计
  • 秒杀的两个判断:
  • 库存够不够(DB中去查而不是相信前端)
  • 用户仅限购一件,根据t_seckill_order表的user_id和goods_id两个属性是否重复从而判断他是否有超购行为
  • 注意秒杀商品扣减库存时,要同时生成订单和秒杀订单,因为秒杀订单表的订单id和订单表的id是外键关联的



引入Jmeter秒杀接口性能:


028_JMeter简单使用 P28 - 07:00


QPS:Query/s,比如:对一个页面访问的请求数

TPS:Transaction/s,比如:请求-查询-响应三个阶段,tps就是3

  • 不同的用户访问商品列表接口
  • 不同的用户访问秒杀接口(这是要更新DB的!!)(发生的问题:慢、商品超卖)


压测后秒杀接口性能优化:

  • 页面缓存:添加读写多更新少数据的缓存
  • Redis、商品列表页面、rul缓存本质还是页面缓存
  • 如果商品量足够大,几百几千页,页面缓存可能也就是几十页甚至几页
  • 优化效果:较优化前qps提升了1倍
  • 对象缓存
  • 处理分布式session时,用redis缓存了用户信息,根据cookie获取user,而user信息往往不会更改。即使更改也是极少部分,且为了保证用户数据信息DB和缓存的一致性,可以延迟双删策略
  • 页面静态化(拆分页面)
  • 商品列表页面
  • 秒杀页面
  • 订单详情页面
  • 静态资源的优化
  • CDN优化
  • 库存超卖
  • 扣减库存前肯定是要根据用户id和商品id去查商品数够不够,那么可将两个id作为联合唯一索引,用以防止一个用户多次抢购的问题
  • 细小优化:将秒杀订单信息放到缓存里便于处理(总的性能提升2倍,主要是因为库存卖完后,库存信息放到redis中就不更新了,用户来抢购时就只走redis而不走DB)
  • 优化过程中仍然出现的问题:10件秒杀商品库存没有超卖,但是订单却生成了90个(SQL解决的:库存减一+条件库存>0)




044_接口优化方向 P44 - 04:33


优化总结:

  • 引入缓存
  • 3个页面缓存
  • 对象缓存
  • 3个页面静态化
  • 重点解决超卖问题:
  • 加索引防止同一用户多次购买
  • sql:update table set stock=stock-1 where stock>0
  • 高并发情形下再次优化--接口优化:
  • redis预减库存,减少对DB的访问
  • 即使redis预减库存,DB仍要交互,高并发情形下咋办?优化下单可用Rabbit MQ队列,缓冲与异步下单
  • redis自己也是服务器,单独部署仍有优化空间:内存标记
  • 整体优化思路:先将秒杀商品信息存放到redis里,用户点击秒杀后,判断有库存则给用户响应“订单排队中”,并将此扣减库存的请求放到Rabbit MQ里,异步生成订单,出单成功后通过轮询方式给响应用户下单成功或失败。(分库分表、DB集群在适当时也可考虑)
  • 加载库存
  • 预减库存
  • 库存不足直接返回;库存足够则封装请求到MQ
  • 后端返回排队中
  • 消息出队进行真实扣减库存
  • 将成功或失败的消息通过MQ返回给用户




052_Redis预减库存 P52 - 05:55


  • 实现初始化Bean时将DB数据加载到Redis中,实现InitializingBean接口,重新afterPropertiesSet方法;预减库存时,为了保证原子性,用了redis的decrement方法,加上库存数量大于0的逻辑可以使得高并发情况下库存不会扣减为负数。(这里也可以用redis锁,异常不能删锁--->配置超时时间;会出现连环删锁怎么办?--->多个命令一次执行---lua脚本,两种实现方式你选哪个?)面试可以说说
  • 内存标记、前端轮询获取数据
  • redis分布式锁优化项目:lua不放客户端会大幅降低qps


  • ThreadLocal
  • 主流企业解决方案:
  • 抢购预约
  • 网关限流
  • 分布式锁 性能不太行






优极限【完整项目实战】半天带你用-springBoot、Redis轻松实现Jav的评论 (共 条)

分享到微博请遵守国家法律