java秒杀高并发------页面相关优化 页面缓存、对象缓存、静态资源缓存

页面缓存

防止瞬间的访问

首先去缓存中取,找到直接返回,没有就渲染返回,在缓存

比如商品列表,访问的话是 goods_list 模板

将数据放到 model中然后去渲染模板

改为 直接返回 html

先创建一个对商品的前缀,用于存入 redis中

GoodsKey设置,设置默认缓存。60s

public class GoodsKey extends BasePrefix {

    private GoodsKey(int exprieSeconds,String prefix) {
        super( exprieSeconds,prefix);
    }

    public static GoodsKey getGoodsList = new GoodsKey(60,"gl");

}

控制器请求商品列表

   @Autowired
    ThymeleafViewResolver thymeleafViewResolver;

    @Autowired
    ApplicationContext applicationContext;


@RequestMapping(value="/to_list", produces="text/html")
    @ResponseBody
    public String list(HttpServletRequest request, HttpServletResponse response, Model model,MiaoshaUser user) {
        model.addAttribute("user", user);
        //取缓存
        String html = redisService.get(GoodsKey.getGoodsList, "", String.class);
        if(!StringUtils.isEmpty(html)) {
            return html;
        }
        List<GoodsVo> goodsList = goodsService.listGoodsVo();
        model.addAttribute("goodsList", goodsList);
//      return "goods_list";
        SpringWebContext ctx = new SpringWebContext(request,response,
                request.getServletContext(),request.getLocale(), model.asMap(), applicationContext );
        //手动渲染
        html = thymeleafViewResolver.getTemplateEngine().process("goods_list", ctx);
        if(!StringUtils.isEmpty(html)) {
            redisService.set(GoodsKey.getGoodsList, "", html);
        }
        return html;
    }

URL缓存

商品详情也修改为URL缓存,也就是页面缓存多个参数。

  @RequestMapping(value = "/to_detail/{goodsId}",produces="text/html")
    @ResponseBody
    public String detail(HttpServletRequest request, HttpServletResponse response,Model model,
                         MiaoshaUser user,
                         @PathVariable("goodsId") long goodsId) {

        model.addAttribute("user", user);
//取缓存
        String html = redisService.get(GoodsKey.getGoodsDetail, ""+goodsId, String.class);
        if(!StringUtils.isEmpty(html)) {
            return html;
        }
        //手动渲染
         GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);
        System.out.println("秒杀价格: "+goods.getMiaoshaPrice());
        model.addAttribute("goods",goods);
        //秒杀状态
        int miaoshaStatus =0;
        //还剩多少秒 -1为结束
        int remainSeconds = 0;
        //
        long startAt = goods.getStartDate().getTime();
        long endtAt = goods.getEndDate().getTime();
        long now = System.currentTimeMillis();
        if(now<startAt){//秒杀没开始
            miaoshaStatus = 0;
            remainSeconds = (int)(startAt-now)/1000;
        }else if (now>endtAt) {//秒杀结束
            miaoshaStatus = 2;
            remainSeconds = -1;
        }else {//秒杀进行中
            miaoshaStatus = 1;
            remainSeconds = 0;
        } 
           model.addAttribute("miaoshaStatus",miaoshaStatus);
        model.addAttribute("remainSeconds",remainSeconds);
        SpringWebContext ctx = new SpringWebContext(request,response,
                request.getServletContext(),request.getLocale(), model.asMap(), applicationContext );
        html = thymeleafViewResolver.getTemplateEngine().process("goods_detail", ctx);
        if(!StringUtils.isEmpty(html)) {
            redisService.set(GoodsKey.getGoodsDetail, ""+goodsId, html);
        }
        return html;
    }

不同页面的不同 goods_id

  redisService.set(GoodsKey.getGoodsDetail, ""+goodsId, html);

对象缓存

之前利用 token将用户实体对应的存入到了redis中

还有个方法是根据用户手机号号来重复数据库中查询用户
改为从redis缓存中取出来

public MiaoshaUser getByMobile(String mobile) {
    //取缓存
   MiaoshaUser user =  redisService.get(MiaoshaUserKey.getByMobile,mobile,MiaoshaUser.class);
    if (user!=null) {
        //return miaoshaUserDao.getByMobile(mobile);
        return user;
    }else {
        //查不到就去数据库中查询
        user =  miaoshaUserDao.getByMobile(mobile);
        if (user!=null){
            redisService.set(MiaoshaUserKey.getByMobile,mobile,user);
        }
        return user;

    }
}

如果有对用户的更新,

先利用上面的查询,如果是空格的直接 抛出异常,
找到了就 存入数据库并删除对象缓存,更新 token(新创建一个实体,传入要改的属性,sql修改)
尽量少修改数据。

页面静态化

2.优点:利用浏览器的缓存

前后端分离

就是后端只写接口,返回json数据就可以了。

这个就比较熟悉了

spring-boot配置静态资源缓存

自动给静态资源Response添加缓存头Cache-Control和Expires值

不会再从服务器中请求,利用了浏览器缓存。

#static
spring.resources.add-mappings=true
spring.resources.cache-period= 3600  //配置缓存多少秒
spring.resources.chain.cache=true
spring.resources.chain.enabled=true
spring.resources.chain.gzipped=true
spring.resources.chain.html-application-cache=true
spring.resources.static-locations=classpath:/static/

如何防止一个用户秒杀一个商品多次(卖超)

对秒杀订单表建一个索引是 用户id和商品id。
每次插入的时候,索引不能重复就不能插入,因为写了事务的注解
就会回滚。

还可以将订单插入到缓存中。

静态资源优化

1.JS/CSS压缩,减少流量

2.多个JS/CSS组合到一个请求,减少连接数

engine,在Nginx的基础上添加。

还有 wbpack 前端打包的。

都可以使用。

3.CDN

并发大的瓶颈在数据库,利用缓存,redis缓存和浏览器缓存,Nginx也可以加缓存

猜你喜欢

转载自blog.csdn.net/qq_28295425/article/details/80240394