秒杀功能(5)页面静态化

这篇是讲页面优化技术的第二项:页面静态化、前后端分离

之前的代码的请求逻辑是:

  1. 客户端请求;
  2. 服务端的servlet或controller接收请求(后端控制路由与渲染页面,整个项目开发的权重大部分在后端);
  3. 调用service,dao层代码完成业务逻辑;
  4. 返回页面;
  5. 页面展现一些动态的代码;

前后端分离的新的方式是:

  1. 浏览器发送请求;
  2. 直接到达html页面(前端控制路由与渲染页面,整个项目开发的权重前移);
  3. html页面负责调用服务端接口产生数据(通过ajax等等);
  4. 后台返回json格式数据,json数据格式因为简洁高效而取代xml;
  5. 填充html,展现动态效果,在页面上进行解析并操作DOM。

优点:

  1. 减少后端服务器的并发/负载压力。除了接口以外的其他所有http请求全部转移到前端nginx上,接口的请求调用tomcat,参考nginx反向代理tomcat。且除了第一次页面请求外,浏览器会大量调用本地缓存。
  2. 即使后端服务暂时超时或者宕机了,前端页面也会正常访问,只不过数据刷不出来而已。
  3. 页面显示的东西再多也不怕,因为是异步加载。
  4. 发现bug,可以快速定位是谁的问题,不会出现互相踢皮球的现象。页面逻辑,跳转错误,浏览器兼容性问题,脚本错误,页面样式等问题,全部由前端工程师来负责。接口数据出错,数据没有提交成功,应答超时等问题,全部由后端工程师来解决。双方互不干扰,前端与后端是相亲相爱的一家人。

更多优点及详情参考:https://blog.csdn.net/dream_cat_forever/article/details/80709503

在本项目中,主要改造的有:GoodsController、MiaoshaController、OrderController。
这边就以MiaoshaController举例吧。
优化前的代码:

 	@RequestMapping("/do_miaosha")
    public String list(Model model, HttpServletResponse response, @RequestParam("goodsId") long goodsId,
                       @CookieValue(value = MiaoshaUserService.COOKI_NAME_TOKEN,required = false) String cookieToken,
                       @RequestParam(value = MiaoshaUserService.COOKI_NAME_TOKEN,required = false) String paramToken) {
        if (StringUtils.isEmpty(cookieToken) && StringUtils.isEmpty(paramToken)) {
            return "login";
        }
        String token = StringUtils.isEmpty(paramToken)?cookieToken:paramToken;
        MiaoshaUser user = userService.getByToken(response,token);//从token中读用户信息
        model.addAttribute("user", user);
        if (user == null) {
            return "login";
        }
        //判断库存
        GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);
        int stock = goods.getStockCount();
        if (stock <= 0) {
            model.addAttribute("errmsg", CodeMsg.MIAO_SHA_OVER.getMsg());
            return "miaosha_fail";
        }
        //判断是否已经秒杀到了
        MiaoshaOrder order = orderService.getMiaoshaOrderByUserIdGoodsId(user.getId(), goodsId);
        if (order != null) {
            model.addAttribute("errmsg", CodeMsg.REPEATE_MIAOSHA.getMsg());
            return "miaosha_fail";
        }
        //3步:减库存 下订单 写入秒杀订单,事务中完成
        OrderInfo orderInfo = miaoshaService.miaosha(user, goods);
        model.addAttribute("orderInfo", orderInfo);
        model.addAttribute("goods", goods);
        return "order_detail";
    }

前后端分离优化后的代码

	@RequestMapping(value = "/do_miaosha", method = RequestMethod.POST)
    @ResponseBody
    public Result<OrderInfo> miaosha(Model model, @RequestParam("goodsId") long goodsId, HttpServletResponse response,
                                     @CookieValue(value = MiaoshaUserService.COOKI_NAME_TOKEN,required = false) String cookieToken,
                                     @RequestParam(value = MiaoshaUserService.COOKI_NAME_TOKEN,required = false) String paramToken) {
        if (StringUtils.isEmpty(cookieToken) && StringUtils.isEmpty(paramToken)) {
            return Result.error(CodeMsg.SESSION_ERROR);//token不存在或失效
        }
        String token = StringUtils.isEmpty(paramToken) ? cookieToken : paramToken;
        MiaoshaUser user = userService.getByToken(response, token);//从token中读用户信息

        //判断库存
        GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);//10个商品,req1 req2
        int stock = goods.getStockCount();
        if (stock <= 0) {
            return Result.error(CodeMsg.MIAO_SHA_OVER);
        }
        //判断是否已经秒杀到了
        MiaoshaOrder order = orderService.getMiaoshaOrderByUserIdGoodsId(user.getId(), goodsId);
        if (order != null) {
            return Result.error(CodeMsg.REPEATE_MIAOSHA);
        }
        //减库存 下订单 写入秒杀订单
        OrderInfo orderInfo = miaoshaService.miaosha(user, goods);
        return Result.success(orderInfo);
    }

可以看到,和原来的代码相比最重要的改变是使用了jason的形式和返回值的改变。当然要添加相应的htm页面。(前端小白htm页面搞了一下午。。这里就省略了)

采用以下配置,使浏览器缓存页面:

#static
spring.resources.add-mappings=true
spring.resources.cache.period=3600
spring.resources.chain.cache=true 
spring.resources.chain.enabled=true
spring.resources.chain.html-application-cache=true
spring.resources.static-locations=classpath:/static/

做完这些后,运行试一下,第一次访问该页面时http头部Status Code为200,表示访问成功;刷新网站再次访问时,Status Code为304,表示 自从上次请求后,请求的网页未修改过。在谷歌浏览器中不能很好的说明,可以在火狐浏览器中查看,头部Cache-Control: max-age=3600,页面是缓存的。

猜你喜欢

转载自blog.csdn.net/Serena0814/article/details/89975728