Redis预减库存的主要思想是减少对数据库的访问。之前的库存减少是直接访问数据库,读取库存。当高并发请求到来时,大量读取数据可能会导致数据库崩溃。思路:在系统初始化时,将商品库存加载到Redis缓存中并保存。收到请求后,现在在Redis中获取商品的库存值,并进行库存预减。如果减量后库存不足,则直接返回逻辑Exception。无需访问数据库即可减少库存。如果库存值正确,下一步就是将请求入队,并立即返回一个值给前端,说明在队列中,然后执行秒杀逻辑,后端队列执行秒杀逻辑,而前端轮询后端发送过来的请求,秒杀成功则返回秒杀,成功则返回失败。(后端请求单线程出队,生成订单,减少库存,遵循逻辑)前端同时轮询前端显示第一步:预减库存/***秒杀界面优化---第一步:系统初始化后将所有商品库存放入缓存*/@OverridepublicvoidafterPropertiesSet()throwsException{Listgoods=goodsService.getGoodsList();如果(货物==空){返回;}for(GoodsVogoodsVo:goods){redisService.set(GoodsKey.getGoodsStock,""+goodsVo.getId(),goodsVo.getStockCount());isOverMap.put(goodsVo.getId(),false);//先初始化每个商品,如果为false,则还有}}/**秒杀界面优化----第二步:预减库存从缓存中*使用redis中的方法减去库存,返回值为减去1后的值**/longstock=redisService.decr(GoodsKey.getGoodsStock,""+goodsId);/*这里的判断不能小于等于,因为减去之后,说明还有一个正常范围*/if(stock<0){isOverMap.put(goodsId,true);//如果没有stock,就设置id对应的product为truereturnResult.error(CodeMsg.MIAO_SHA_NO_STOCK);}预减库存:1.首先读取所有数据,初始化到缓存中,用stock+goodid形成存储在Redis中,2.秒杀时,先查看预减库存。从redis中,使用decr减去对应商品的库存。如果库存小于0,说明此时库存不足,不需要访问数据库。直接抛异常标记内存:因为接口优化了很多基于Redis的缓存操作,当并发很高的时候,也会给Redis服务器带来很大的负担。如果能减少对Redis服务器的访问,也能达到优化的效果。因此,可以添加一个内存映射来标记对应产品的库存是否还在。在接入Redis之前,可以在map中获取到对应商品的stockmark,不接入Redis也可以判断没有库存。1、生成一个map,在初始化的时候,将所有商品的id作为key存入map中,标记为false。privateMapisOverMap=newHashMap();/***秒杀界面优化---第一步:系统初始化后,将所有商品库存放入缓存*/@OverridepublicvoidafterPropertiesSet()throwsException{Listgoods=goodsService.getGoodsList();}如果(货物==空){返回;}for(GoodsVogoodsVo:goods){redisService.set(GoodsKey.getGoodsStock,""+goodsVo.getId(),goodsVo.getStockCount());isOverMap.put(goodsVo.getId(),false);//先初始化每个商品,如果为false,则还有}}/**重新优化:优化库存后请求,不要通过判断值访问redis对应地图的**/booleanisOver=isOverMap.get(goodsId);如果(isOver){returnResult.error(CodeMsg.MIAO_SHA_NO_STOCK);}if(stock<0){isOverMap.put(goodsId,true);//如果没有库存,将id商品对应的map设置为true2.预减库存前,从map中取出mark,如果标记为false,则表示有库存,以及,3.预减库存,当遇到库存不足时,将商品的flag设置为true,表示商品库存不足。这样后面的请求都会被拦截,不需要再访问redis进行预减库存。