页面缓存、URL缓存、对象缓存

转载自:https://blog.csdn.net/weixin_38035852/article/details/81054397

页面缓存

优化:这种缓存技术一般用于不会经常变动信息,并且访问次数较多的页面,这样就不用每次都动态加载。

商品列表页 页面缓存:1.取缓存 ()2.手动渲染 3.结果输出

Thymeleaf 的页面渲染技术。

   @ResponseBody
    @RequestMapping(value = "/to_list",produces = "text/html")
    public String to_list(HttpServletResponse response, HttpServletRequest request,Model model, MiaoshaUser user){//为了方便手机端 移动端,将参数放在请求中
        /*页面缓存*/
        String html = redisService.get(GoodsKey.getGoodsList,"",String.class);
        if (!StringUtils.isEmpty(html)){//从redis 中取, 取得到返回,取不到 手动渲染
            return html;
        }
        model.addAttribute("user",user);
        List<GoodsVo> goodsList = goodsService.getGoodsList();
        model.addAttribute("goodsList",goodsList);
//        return "goods_list";
        /*手动渲染 利用Thymeleaf 的 ThymeleafViewResolver*/
        SpringWebContext ctx = new SpringWebContext(request,response,request.getServletContext(),request.getLocale(),
                model.asMap(), applicationContext); // model 就是将参数存入 ,其中的所有参数 都是为了将页面渲染出来 放入其中,在返回一个静态的html源码
        /*利用 getTemplateEngine()方法的process() 方法,需要传入模板名称和context 变量*/
        html = thymeleafViewResolver.getTemplateEngine().process("goods_list",ctx);//ctx + 模板 返回源码
        /*得到手动渲染的模板*/
        if (!StringUtils.isEmpty(html)){    //不是空,存入缓存
            redisService.set(GoodsKey.getGoodsList,"",html);
        }
        return html;
    }
当访问list页面的时候,从缓存中取如果取到就返回这个html,(这里方法的返回格式已经设置为text/HTM,这样就是返回html的源代码),如果取不到,利用ThymeleafViewResolver的getTemplateEngine().process和我们获取到的数据,渲染模板

并存入缓存,然后返回给前端。

一般这个页面缓存时间,也不会很长,防止数据的时效性很低。但是可以防止短时间大并发访问。

url缓存

这里的url缓存相当于页面缓存--只是针对详情页{goodsid} 

不同的详情页 显示不同缓存页面+渲染 实质一样

对象缓存

相比页面缓存是更细粒度缓存  + 缓存 更新。在实际项目中, 不会大规模使用页面缓存,因为涉及到分页,一般只缓存前面1-2页。

对象缓存就是 当用到用户数据的时候,可以从缓存中取出。比如:更新用户密码


/** 将从数据库取对象 利用优化变为从缓存中取 对象数据
 *
 * @param id
 * @return
 */
public MiaoshaUser getById(Long id){
    //取缓存
    MiaoshaUser user = redisService.get(MiaoshaUserKey.getByName,""+id,MiaoshaUser.class);
    if (user != null){//取到返回
        return user;
    }
    //取不到 从数据库里取 再放到 缓存里
    user =  miaoshaUserDao.getById(id);
    if (user !=null){
        redisService.set(MiaoshaUserKey.getByName,""+id,user);
    }
    return user;
}


/**更新用户密码方法: 涉及到对象缓存 ---若更新对象缓存的相关的数据 要处理缓存
 *  同步数据库和缓存的信息,不然会造成数据不一致的情况
 * */
public boolean updatePassword(String token,long id,String formPassword){
    /*根据id 取出对应用户,更新对应数据*/
    MiaoshaUser user = getById(id);
    if (user == null){//如果没有该用户,说明 手机号不存在
        throw  new GlobalException(CodeMsg.LOGIN_ERROR_USER_NOT_ERROR);
    }
    // 更新数据库 信息
    MiaoshaUser updateUser = new MiaoshaUser();
    updateUser.setId(id);
    /*设置密码 到数据库 ,这时候 应该是formPassword ,更新密码一定是先在前端填入 密码,然后前端做 一次 加密传进来*/
    updateUser.setPassword(Md5Util.formPassToDBPass(formPassword,user.getSalt()));
    miaoshaUserDao.updatePassword(updateUser);
    // 更新完数据库信息,防止缓存中信息不一致,处理缓存 且涉及到所有该对象的缓存都需要处理
    // 一个 是 根据 token 获取对象,所以需要更新 token key 的缓存对象数据, 一个是根据id 获取对象,同理
    /** 处理缓存:
     *  1. 删除相关缓存数据
     *  2. 更新相关缓存中的数据
     * */
    redisService.delete(MiaoshaUserKey.getByName,""+id);//该对象缓存可以直接删,因为没有可以从数据取
    //但是token 缓存不能删除,而是应该修改重新设置,不然就无法登陆了(因为我们登陆是从缓存中取)
    user.setPassword(updateUser.getPassword());
    //将对象 携带新的密码放入缓存
    redisService.set(MiaoshaUserKey.token,token,user);
    return true;
}
getById()方法就是一个对象缓存方法,先从缓存中取,取不到,数据库中取。

但是这里会设计一个缓存一致性的问题:处理缓存 https://blog.csdn.net/ZLHZHJ/article/details/80176988  详细

1.更新缓存后保证数据库中数据和缓存数据一致性。 可以选择淘汰缓存和更新缓存

淘汰:性价比高,仅仅会设计一次未命中,再从数据库取 

更新:操作复杂,涉及到对应的业务逻辑。

更新缓存很直接,但是涉及到本次更新的数据结果需要一堆数据运算(例如更新用户余额,可能需要先看看有没有优惠券等),复杂度就增加了。而淘汰缓存仅仅会增加一次cache miss,代价可以忽略,所以建议淘汰缓存)

2.若一定要更新,比如登陆状态下,更新密码,那一定要更新缓存,因为 session从缓存中拿,密码不一致,会导致登陆失效

这里先淘汰缓存,在更新数据库信息。(若先更新在淘汰,淘汰失败缓存中有脏数据)

保证数据一致性。

当然也有 其他不一致的缓存情况,具体分析。
 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值