【系统开发】尚硅谷 - 谷粒商城项目笔记(五):分布式缓存

这篇具有很好参考价值的文章主要介绍了【系统开发】尚硅谷 - 谷粒商城项目笔记(五):分布式缓存。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


分布式缓存

缓存使用场景

【系统开发】尚硅谷 - 谷粒商城项目笔记(五):分布式缓存

【系统开发】尚硅谷 - 谷粒商城项目笔记(五):分布式缓存

【系统开发】尚硅谷 - 谷粒商城项目笔记(五):分布式缓存

redis作缓存中间件

引入redis依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

配置redis

# ip地址
spring.redis.host=124.222.43.217
# 端口
spring.redis.port=6379

堆外内存溢出

【系统开发】尚硅谷 - 谷粒商城项目笔记(五):分布式缓存

<!--引入redis,排除lettuce,使用jedis-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <exclusions>
        <exclusion>
            <groupId>io.lettuce</groupId>
            <artifactId>lettuce-core</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
</dependency>

缓存失效问题

缓存穿透

【系统开发】尚硅谷 - 谷粒商城项目笔记(五):分布式缓存

缓存雪崩

【系统开发】尚硅谷 - 谷粒商城项目笔记(五):分布式缓存

缓存击穿

【系统开发】尚硅谷 - 谷粒商城项目笔记(五):分布式缓存

Redisson分布式锁

导入依赖

<!-- 以后使用redisson作为所有分布式锁,分布式对象等功能框架 -->
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.12.0</version>
</dependency>

redisson配置类

@Configuration
public class MyRedissonConfig {
    @Bean(destroyMethod="shutdown")
    RedissonClient redissonClient() throws IOException {
        Config config = new Config();
        // 这里必须以redis://开头,否则会报错
        config.useSingleServer().setAddress("redis://124.222.43.217:6379");
        return Redisson.create(config);
    }
}

可重入锁

可重入锁解释:无论是公平方式还是非公平方式,进门坐下来之后,你可以问医生问题一次,两次,无数次( 重入),只要你还坐着,你都可以问,但是一旦起身离开座位,你的位置就会被抢,除非没人排队,不然你失去了提问的资格。

@ResponseBody
@GetMapping("/hello")
public String hello() {
    //1 获取一把锁,只要锁的名字一样,就是同一把锁
    RLock lock = redisson.getLock("my-lock");
    // 2 加锁
    lock.lock(); // 阻塞式等待,默认加的锁都是30s
    // 锁的自动续期,如果业务超长,运行期间自动给锁续上新的30s。不用担心业务时间长,锁自动过期被删除
    // 加锁的业务只要运行完成,就不会给当前锁续期,即使不手动解锁,锁默认在30s以后自动删除
    lock.lock(10, TimeUnit.SECONDS); //10s自动解锁,自动解锁时间一定要大于业务的执行时间
    // lock.lock(10, TimeUnit.SECONDS); // 锁时间到了之后,不会自动续期
    try {
        System.out.println("加锁成功,执行业务" + Thread.currentThread().getId());
        // 模拟长业务5s
        Thread.sleep(5000);
    } catch (Exception e) {

    }finally {
        // 3 解锁
        System.out.println("释放锁" + Thread.currentThread().getId());
        lock.unlock();
    }
    return "hello";
}

读写锁

读锁(共享锁)会等待写锁(互斥锁,排他锁)释放,保证一定能读到最新数据

写锁也会等待读锁释放,保证写数据时不能读取数据

总结:读写互斥,不管是先读后写,还是先写后读,都会进行阻塞等待

    @GetMapping("/write")
    @ResponseBody
    public String writeValue() {
        RReadWriteLock lock = redisson.getReadWriteLock("rw-lock");
        String s = "";
        // 改数据,加写锁
        RLock rLock = lock.writeLock();
        try {
            rLock.lock();
            System.out.println("nihao");
            s = UUID.randomUUID().toString();
            Thread.sleep(30000);
            redisTemplate.opsForValue().set("writeValue", s);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            rLock.unlock();
        }
        return s;
    }

    @GetMapping("/read")
    @ResponseBody
    public String readValue() {
        RReadWriteLock lock = redisson.getReadWriteLock("rw-lock");
        String s = "";
        // 读数据,加读锁
        RLock rLock = lock.readLock();
        try {
            rLock.lock();
            s = redisTemplate.opsForValue().get("writeValue");
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            rLock.unlock();
        }
        return s;
    }

缓存一致性解决

双写模式:写操作后,同时修改缓存

失效模式:写操作后,删除缓存

【系统开发】尚硅谷 - 谷粒商城项目笔记(五):分布式缓存

【系统开发】尚硅谷 - 谷粒商城项目笔记(五):分布式缓存

【系统开发】尚硅谷 - 谷粒商城项目笔记(五):分布式缓存

缓存-SpringCache

简介

【系统开发】尚硅谷 - 谷粒商城项目笔记(五):分布式缓存

【系统开发】尚硅谷 - 谷粒商城项目笔记(五):分布式缓存

【系统开发】尚硅谷 - 谷粒商城项目笔记(五):分布式缓存

@Cacheable

引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

properties配置

# 使用redis作为缓存
spring.cache.type=redis
# 设置有效时间,毫秒为单位,3600*1000
spring.cache.redis.time-to-live=3600000
# 是否使用缓存前缀
spring.cache.redis.use-key-prefix=true
# 指定缓存前缀,如果不指定,则默认使用注解中value指向的值(分组名),如果value没有指向任何值,则无缓存前缀
# spring.cache.redis.key-prefix=WSKH_CACHE_
# 是否缓存空值,防止缓存穿透
spring.cache.redis.cache-null-values=true
spring.session.store-type=redis

启动类上加注解,开启缓存

@EnableCaching

在要开启缓存的方法上加上@Cacheable注解,示例如下所示:

// 每一个需要缓存的数据我们都要指定放到哪个名字的缓存。【缓存的分区】
// 当前方法的结果需要缓存,如果缓存中有,方法不调用,如果缓存中没有,会调用方法,最后将方法的结果放入缓存
// value = {"category"} 表示:属于哪个缓存分区(分组),当没有指定缓存前缀的时候,就会使用这个分组名作为前缀
// key = "#root.method.name" 表示:将方法名作为存入redis中的键
// sync = true 表示:是否为同步代码块
@Cacheable(value = {"category"},key = "#root.method.name",sync = true)  
@Override
public List<CategoryEntity> getLevel1Categorys() {
    long l = System.currentTimeMillis();
    List<CategoryEntity> categoryEntities = baseMapper.selectList(new QueryWrapper<CategoryEntity>().eq("parent_cid", 0));
    System.out.println("消耗时间," + (System.currentTimeMillis() - 1));
    return categoryEntities;
}

自定义缓存配置

默认缓存数据是保存JDK序列化后的数据,一般业务上需要使用JSON格式进行缓存的存储(JSON具有跨语言,跨平台的高兼容性)

@EnableConfigurationProperties(CacheProperties.class)
@Configuration
@EnableCaching
public class MyCacheConfig {
    @Bean
    RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties) {
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
        config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
        config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
        CacheProperties.Redis redisProperties = cacheProperties.getRedis();
        if (redisProperties.getTimeToLive() != null) {
            config = config.entryTtl(redisProperties.getTimeToLive());
        }
        if (redisProperties.getKeyPrefix() != null) {
            config = config.prefixKeysWith(redisProperties.getKeyPrefix());
        }
        if (!redisProperties.isCacheNullValues()) {
            config = config.disableCachingNullValues();
        }
        if (!redisProperties.isUseKeyPrefix()) {
            config = config.disableKeyPrefix();
        }
        return config;
    }
}

@CacheEvict

  • value = “category”:指定分组名,即缓存默认前缀
  • allEntries = true:指定删除value指向的分组下的所有缓存数据
  • key = " ‘myKey’ ":指定缓存的key值,如果是普通字符串,则需要在双引号中加单引号,将其包裹
@CacheEvict(value = "category",allEntries = true)  // 失效模式
@CachePut // 双写模式
@Transactional
@Override
public void updateCasecade(CategoryEntity category) {
    this.updateById(category);
    categoryBrandRelationService.updateCategory(category.getCatId(), category.getName());
}

同时清除多个缓存

【系统开发】尚硅谷 - 谷粒商城项目笔记(五):分布式缓存

@CachePut

双写模式,修改完数据库后,将返回的结果更新到缓存中,如果方法返回修饰符为void,那么就不能使用@CachePut注解

原理与不足

【系统开发】尚硅谷 - 谷粒商城项目笔记(五):分布式缓存

【系统开发】尚硅谷 - 谷粒商城项目笔记(五):分布式缓存文章来源地址https://www.toymoban.com/news/detail-493397.html

到了这里,关于【系统开发】尚硅谷 - 谷粒商城项目笔记(五):分布式缓存的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 谷粒商城篇章5 ---- P173-P192 ---- 检索服务【分布式高级篇二】

    目录 1 检索服务  1.1 搭建页面环境 1.1.1 引入依赖 1.1.2 将检索页面放到gulimall-search的src/main/resources/templates/目录下 1.1.3 调整搜索页面 1.1.4 将静态资源放到linux的nginx相关映射目录下/root/docker/nginx/html/static/ search/ 1.1.5 SwitchHosts配置域名转发 1.1.6 测试 1.1.7 nginx配置 1.1.8 网关配

    2024年02月15日
    浏览(31)
  • 1+X 云计算运维与开发(中级)案例实战——分布式部署集群应用商城系统

    学而不思则罔,思而不学则殆。 IP 主机名 节点 192.168.200.10 mycat Mycat 中间件服务节点 192.168.200.20 db1 MariaDB 数据库集群主节点 192.168.200.30 db2 MariaDB 数据库集群从节点 192.168.200.40 zookeeper1 集群节点 192.168.200.50 zookeeper2 集群节点 192.168.200.60 zookeeper3 集群节点 192.168.200.70 redis 消息队

    2023年04月23日
    浏览(50)
  • 谷粒商城笔记+踩坑(1)——架构、项目环境搭建、代码生成器

     导航: 谷粒商城笔记+踩坑汇总篇_谷粒商城笔记踩坑6_vincewm的博客-CSDN博客 目录 1、项目介绍 1.1 微服务架构图 1.2. 微服务划分图 2、项目环境搭建 2.1. 虚拟机搭建环境 2.2. Linux安装docker、配置镜像加速 2.3. docker配置mysql、设置自启动 2.3.1、安装mysql5.7 2.3.2、修改mysql配置文件

    2024年02月01日
    浏览(42)
  • 学习笔记20230629 -- 《分享在jsp分布式项目支援开发衍生功能时遇到和解决的问题》

    1.jsp项目的页面跳转,需要后端的java技术做支撑,在java的接口文件中写跳转接口,使用ajax去请求这个跳转接口,将返回的数据(html标签代码),放到当前页面或弹窗的\\\"content\\\"属性中 2.使用原生js写法实现 全选 功能和删除功能的逻辑思想 将每条回显数据的唯一id值作为每一条

    2024年02月11日
    浏览(71)
  • 谷粒商城学习笔记

    1)、电商模式 2)、谷粒商城 谷粒商城是一个 B2C 模式的电商平台,销售自营商品给客户。 1、项目微服务架构图 2、微服务划分图 3、项目技术特色 4、项目前置要求 分布式是指将不同的业务分布在不同的地方。 集群指的是将几台服务器集中在一起,实现同一业务。 例如:

    2024年01月16日
    浏览(34)
  • 【笔记/后端】谷粒商城高级篇

    全文检索工具:快速储存、搜索和分析海量数据。 Index (索引) → Mysql的库 动词,相当于MySQL中的insert; 名词,相当于MySQL中的Database。 Type (类型) → Mysql的表(过时) 在Index中,可以定义一个或多个类型。类似于MySQL中的Table;每一种类型的数据放在一起。 Document (文档) →

    2024年02月02日
    浏览(32)
  • 【笔记】谷粒商城高级篇

    全文检索工具:快速储存、搜索和分析海量数据。 Index (索引) → Mysql的库 动词,相当于MySQL中的insert; 名词,相当于MySQL中的Database。 Type (类型) → Mysql的表(过时) 在Index中,可以定义一个或多个类型。类似于MySQL中的Table;每一种类型的数据放在一起。 Document (文档) →

    2023年04月21日
    浏览(33)
  • 谷粒商城第一天-项目概述、架构、Linux环境搭建

    目录 一、学习的内容 一、常见的商城模式 二、谷粒商城项目的微服务架构 三、谷粒商城项目的微服务划分 四、谷粒商城项目的亮点 五、微服务的基本的概念 二、完成的进度 三、学到的东西 四、总结 6月9日正式下决心开始学习谷粒商城项目,之前早就听说谷粒商城项目的

    2024年02月10日
    浏览(28)
  • 谷粒商城项目|es的应用场景及常见问题

    es是什么 es多被用于搜索聚合分析引擎 是分布式的可以高性能查询的引擎 es应用场景 为什么不用MYSQL而用es es将数据存在内存中且可以分布式的存储数据 商品上架 商品在es中的保存 1.在es中建立索引 spu sku spu sku保存在一起防止分布查询 为了防止对象数组扁平化,商品属性字段

    2024年01月17日
    浏览(33)
  • 谷粒商城笔记(详细版) IDEA2021 高级篇1(2022/11/9)

    谷粒商城笔记(详细版) IDEA2021 基础篇(1/3). 谷粒商城笔记(详细版) IDEA2021 基础篇(2/3). ES6 VUE 基础篇前端笔记 谷粒商城笔记(详细版) IDEA2021 基础篇(3/3). [谷粒商城笔记(详细版) IDEA2021 高级篇(第1篇) 索引对应mysql中的库 类型对应Mysql中的数据表 文档对应mysql中的一条条数据 在我们

    2023年04月09日
    浏览(25)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包