欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

javaweb商城秒杀系统--页面级高并发秒杀优化Redis缓存+静态化分离(四)

程序员文章站 2022-06-20 08:46:01
...

因为并发的瓶颈最大就是出现在数据库上,所以我们最有效的方式就是缓存
一、页面缓存
1.取缓存
2.手动渲染模版
3.结果输出

//商品列表
@RequestMapping(value = "/to_list",produces = "text/html")
@ResponseBody
public String toLogin(HttpServletRequest request,HttpServletResponse response
                                        , Model model, MiaoshaUser user ){
    //return "goods_list";
    //先从缓存中去页面代码
    String html=redisService.get(GoodsKey.getGoodsList,"",String.class);
    //如果不是空就把取出来的页面直接返回去
    if(!StringUtils.isEmpty(html)){
        return html;
    }
    //第一步查询商品列表
    List<GoodsVo> goodsVoList=goodsService.getGoodsVoList();
    model.addAttribute("goodsList",goodsVoList);
    SpringWebContext swc=new SpringWebContext(request,response
           ,request.getServletContext(),request.getLocale(),model.asMap(),applicationContext);
    //手动渲染
    html=thymeleafViewResolver.getTemplateEngine().process("goods_list",swc);
    if(!StringUtils.isEmpty(html)){
        redisService.set(GoodsKey.getGoodsList,"",html);
    }
    return html;
}

//使用了缓存的详情页
//使用了缓存的详情页
   /* @RequestMapping(value = "/to_detail/{goodsId}",produces = "text/html")
    @ResponseBody
    public String toDetail(HttpServletRequest request,HttpServletResponse response
                  ,Model model, MiaoshaUser user, @PathVariable("goodsId") Long goodsId){
    //首先取缓存
        String html=redisService.get(GoodsKey.getGoodsList,""+goodsId,String.class);
        if(!StringUtils.isEmpty(html)){
            return html;
        }
        //手动渲染
        model.addAttribute("user",user);
        //得到商品id然后通过id获取商品的详情
        GoodsVo goodsVo=goodsService.getGoosVoByGoodsId(goodsId);
        model.addAttribute("goods",goodsVo);
        //获取一个秒杀开始时间
         long startAt=goodsVo.getStartDate().getTime();
        //获取一个秒杀结束时间
        long endAt=goodsVo.getEndDate().getTime();
        //获取当前时间
        long now=System.currentTimeMillis();
        int miaoshaStatus=0;//设置一个状态
        int remainSeconds=0;//还剩多少时间
        if(now<startAt){
            //秒杀还没有开始
            miaoshaStatus=0;
            remainSeconds= (int) ((startAt-now)/1000);
        }else if(now>endAt){
            //秒杀结束
            miaoshaStatus=2;
            remainSeconds=-1;
        }else {
            //秒杀进行时
            miaoshaStatus=1;
            remainSeconds=0;
        }

        //秒杀时的状态和时间传入到前端页面
        model.addAttribute("miaoshaStatus",miaoshaStatus);
        model.addAttribute("remainSeconds",remainSeconds);
        SpringWebContext swc=new SpringWebContext(request,response
                ,request.getServletContext(),request.getLocale(),model.asMap(),applicationContext);

        //手动渲染
        html=thymeleafViewResolver.getTemplateEngine().process("goods_detail",swc);
        if(!StringUtils.isEmpty(html)){
            redisService.set(GoodsKey.getGoodsDetail,""+goodsId,html);
        }
    return html;
       // return "goods_detail";
    }

二、对象缓存
失效:应用程序先从缓存中取数据,没有得到,则从数据库中取,成功后,放到缓存中;

命中:应用程序从缓存中取数据,取得后返回;

更新:先将数据存到数据库中,成功后,再让缓存失效;

对象缓存之后,若有数据更新,一定要更新缓存,否则会出现缓存不一致的情况
三、页面静态化
简单来说,就是使用html进行页面展示,ajax进行前后端交互,流行的框架有Vue、Angular。静态化可以使html代码在客户端缓存,不需要去请求服务器。

<!DOCTYPE HTML>
<html>
<head>
    <title>订单详情</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <!-- jquery -->
    <script type="text/javascript" src="/js/jquery.min.js"></script>
    <!-- bootstrap -->
    <link rel="stylesheet" type="text/css" href="/bootstrap/css/bootstrap.min.css" />
    <script type="text/javascript" src="/bootstrap/js/bootstrap.min.js"></script>
    <!-- jquery-validator -->
    <script type="text/javascript" src="/jquery-validation/jquery.validate.min.js"></script>
    <script type="text/javascript" src="/jquery-validation/localization/messages_zh.min.js"></script>
    <!-- layer -->
    <script type="text/javascript" src="/layer/layer.js"></script>
    <!-- md5.js -->
    <script type="text/javascript" src="/js/md5.min.js"></script>
    <!-- common.js -->
    <script type="text/javascript" src="/js/common.js"></script>
</head>
<body>
<div class="panel panel-default">
  <div class="panel-heading">秒杀订单详情</div>
  <table class="table" id="goodslist">
        <tr>  
        <td>商品名称</td>  
        <td colspan="3" id="goodsName"></td> 
     </tr>  
     <tr>  
        <td>商品图片</td>  
        <td colspan="2"><img  id="goodsImg" width="200" height="200" /></td>  
     </tr>
      <tr>  
        <td>订单价格</td>  
        <td colspan="2"  id="orderPrice"></td>  
     </tr>
     <tr>
     		<td>下单时间</td>  
        	<td id="createDate" colspan="2"></td>  
     </tr>
     <tr>
     	<td>订单状态</td>  
        <td id="orderStatus">
        </td>  
        <td>
        	<button class="btn btn-primary btn-block" type="submit" id="payButton">立即支付</button>
        </td>
     </tr>
      <tr>
     		<td>收货人</td>  
        	<td colspan="2">小张  1735342429</td>
     </tr>
     <tr>
     		<td>收货地址</td>  
        	<td colspan="2">杭州市滨江区</td>
     </tr>
  </table>
</div>
</body>
</html>
<script>
function render(detail){
	var goods = detail.goods;
	var order = detail.order;
	$("#goodsName").text(goods.goodsName);
	$("#goodsImg").attr("src", goods.goodsImg);
	$("#orderPrice").text(order.goodsPrice);
	$("#createDate").text(new Date(order.createDate).format("yyyy-MM-dd hh:mm:ss"));
	var status = "";
	if(order.status == 0){
		status = "未支付"
	}else if(order.status == 1){
		status = "待发货";
	}
	$("#orderStatus").text(status);
	
}

$(function(){
	getOrderDetail();
})

function getOrderDetail(){
	var orderId = g_getQueryString("orderId");
	$.ajax({
		url:"/order/detail",
		type:"GET",
		data:{
			orderId:orderId
		},
		success:function(data){
			if(data.code == 0){
				render(data.data);
			}else{
				layer.msg(data.msg);
			}
		},
		error:function(){
			layer.msg("客户端请求有误");
		}
	});
}
///////////////////////////////////
// 获取url参数
function g_getQueryString(name) {
    var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
    var r = window.location.search.substr(1).match(reg);
    if(r != null) return unescape(r[2]);
    return null;
};
//设定时间格式化函数,使用new Date().format("yyyyMMddhhmmss");
Date.prototype.format = function (format) {
    var args = {
        "M+": this.getMonth() + 1,
        "d+": this.getDate(),
        "h+": this.getHours(),
        "m+": this.getMinutes(),
        "s+": this.getSeconds(),
    };
    if (/(y+)/.test(format))
        format = format.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
    for (var i in args) {
        var n = args[i];
        if (new RegExp("(" + i + ")").test(format))
            format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? n : ("00" + n).substr(("" + n).length));
    }
    return format;
};
///////////////////////////////////


</script>