高并发秒杀项目——05

高并发秒杀项目——页面优化

页面缓存+URL缓存+对象缓存

页面缓存
改造GoodsController中的方法,加入ThymeleafViewResolver注解

   @RequestMapping(value = "/to_list",produces ="text/html" )
    @ResponseBody
    public String list(HttpServletRequest request, HttpServletResponse response, Model model, MiaoshaUser user) {
        model.addAttribute("user", user);
        //查询商品列表,包括商品和秒杀商品
        List<GoodsVo> goodsList = goodsService.listGoodsVo();
        model.addAttribute("goodsList", goodsList);
//        return "goods_list";
//        取缓存
        String html = redisService.get(GoodsKey.getGoodsList,"",String.class);
        if (!StringUtils.isEmpty(html)){
            return html;
        }
        //手动渲染
        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;
    }

GoodsKey :作为页面缓存的缓存Key的前缀,缓存有效时间,一般设置为1分钟

public class GoodsKey extends BasePrefix{
    public GoodsKey(int expireSeconds, String prefix) {
        super(expireSeconds, prefix);
    }

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

}

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.getGoodsList,"",String.class);
        if (!StringUtils.isEmpty(html)){
            return html;
        }

        GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);
        model.addAttribute("goods", goods);
        //转化为毫秒
        long startAt = goods.getStartDate().getTime();
        long endAt = goods.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 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;
    }

对象缓存
MiaoshaUserService里面增加getById方法,先去取缓存,如果缓存中拿不到,那么就去取数据库,然后再设置到缓存中去

  public MiaoshaUser getById(long id){
        //取缓存
        MiaoshaUser user = redisService.get(MiaoshaUserKey.getById, ""+id, MiaoshaUser.class);
        if (user != null){
            return user;
        }
        //取数据库
        user = miaoshaUserDao.getById(id);
        if (user != null){
            redisService.set(MiaoshaUserKey.getById, ""+id, user);
        }
        return user;
//        return miaoshaUserDao.getById(id);
    }

更新用户密码:更新数据库与缓存,一定保证数据一致性,修改token关联的对象以及id关联的对象,先更新数据库后删除缓存,不能直接删除token,删除之后就不能登录了,再将token以及对应的用户信息一起再写回缓存里面去。

public boolean updatePassword(String token, long id, String formPass){
    //取user对象
    MiaoshaUser miaoshaUser = getById(id);
    if (miaoshaUser == null){
        throw new GlobalException(CodeMsg.MOBILE_NOT_EXIST);
    }
    //更新数据库
    MiaoshaUser toBeUpdate = new MiaoshaUser();
    toBeUpdate.setId(id);
    toBeUpdate.setPassword(MD5Util.formPassToDBPass(formPass, miaoshaUser.getSalt()));
    miaoshaUserDao.update(toBeUpdate);
    //处理缓存
    redisService.delete(MiaoshaUserKey.getById, ""+id);
    miaoshaUser.setPassword(toBeUpdate.getPassword());
    redisService.set(MiaoshaUserKey.token, token, miaoshaUser);//更新token
    return true;
}

RedisService里面的delete方法

public Boolean delete(KeyPrefix prefix, String key){
    Jedis jedis = null;
    try {
        jedis = jedisPool.getResource();
        String realPrefix = prefix.getPrefix() + key;
        long ret = jedis.del(realPrefix);
        return ret > 0;
    }finally {
        returnToPool(jedis);
    }
}

MiaoshaUserDao 中的Update方法

@Update("update miaosha_user set password = #{password} where id = #{id}")
public void update(MiaoshaUser toBeUpdate);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值