Spring Boot 2精髓 - (14) Cache

spring boot

Spring Cache对Cache进行了抽象,提供了@Cacheable@CachePut@CacheEvict等注解。SpringBoot应用基于SpringCache,既提供了基于内存实现的缓存管理器,可以用于单体应用系统,也集成了Redis、EhCache等缓存服务器,可用于大型系统或者分布式系统。

Cache

应用系统缓存通常有以下作用:

  • 缓存Web系统的输出,如伪静态页面
  • 缓存系统中不经常改变的业务数据,如用户权限、字典数据、配置信息等

Cache的组件和概念

  • CacheManager,用来创建、管理、管理多个命名唯一的Cache,如组织机构缓存、菜单项的缓存、菜单树的缓存等
  • Cache 类似Map那样的Key-Value存储结构,Value部分通常包含了缓存的对象,通过Key来取得缓存对象
  • 缓存项,存放在缓存里的对象,常常需要实现序列化接口,以支持分布式缓存
  • Cache存储方式,缓存组件可以将对象放到内存或其他缓存服务器上,Spring Boot提供了一个基于ConcurrentMap的缓存,同时也集成了Redis、EhCache2.x、JCache缓存服务器等
  • 缓存策略,通常Cache还可以有不同的缓存策略,如设置缓存最大的容量,缓存项的过期时间
  • 分布式缓存,缓存通常按照缓存数据类型存放在不同缓存服务器上,或者同一类型的缓存按照某种算法、不同Key的数据存放在不同的缓存服务器上
  • Cache Hit,从Cache中取得期望的缓存项,我们通常称之为缓存命中。如果没有命中则称之为Cache Miss,意味着需要从数据来源处重新取出井放回Cache中
  • Cache Miss,缓存丢失,根据Key没有从缓存中找到对应的缓存项
  • Cache Evication,缓存清除操作
  • Hot Data,热点数据,缓存系统能调整算法或者内部存储方式,使得最有可能频繁访问的数据能被尽快访问到
  • On-Heap, Java分配对象都是在堆内存中,有最快的获取速度。由于虚拟机的垃圾回收管理机制,缓存放入过多的对象会导致垃圾回收时间过长,从而有可能影响性能
  • off-Heap,堆外内存,对象存放在虚拟机分配的堆外内存中,因此不受垃圾回 收管理机制的管理,不影响系统性能,但堆外内存的对象要被使用,还要序列化成堆内对象。很多缓存工具会把不常用的对象放到堆外,把热点数据放到堆内

Cache的单体应用

使用专有的Cache服务器

使用一二级缓存服务器

Spring Boot Cache

Spring Boot本身提供了一个基于ConcurrentHashMap的缓存机制,也集成了EhCache2.x、JCache CJSR-107、EhCache3.x、 Haz巳least、Infinispan),还有 Couchbase、Redis等。
Spring Boot应用通过注解的方式使用统一的缓存,只需在方法上使用缓存注解即可,其缓存的具体实现依 赖于选择的目标缓存管理器。

使用@Cacheable

集成 Spring Cache

依赖:

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>

appliaction.properties 中配置

1
spring.cache.type=Simple
  • Simple,基于 ConcurrentHashMap实现的缓存,适合单体应用或者开发环境使用
  • none,关闭缓存,比如开发阶段为了确保功能正确, 可以先禁止使用缓存
  • redis,使用 Redis作为缓存,还需要在pom中增加 Redis依赖
  • Generic,用户自定义缓存实现,用户需要实现一个org.springframework.cache.CacheManager的实现
  • 其他还有 JCache、 EhCache2.x, Hazelcast等

注解@EnableCaching打开缓存功能

注释驱动缓存

@Cacheable

注解@Cacheable声明了方法的结果是可缓存的,如果缓存存在,则目标方法不会被调用,直接取出缓存。
可以为方法声明多个缓存,如果至少有一个缓存有缓存项,则其缓存项将被返回。

Key生成器

Spring使用了KeyGenerator类来根据方法参数生成 Key

@CachePut

注解CachePut总是会执行方法体,井且使用返回的结果更新缓存

@CacheEvict

注解CacheEvict 用于删除缓存项或者清空缓存,CacheEvict 可以指定多个缓存名字来清空多个缓存

CacheEvict可以清空缓存中的所有项目,此时使用allEntries=true来删除清空缓存

@Caching

注解Caching可以混合以上各种注解,可以在Caching标签中混合@Cacheable、@CachePut、@CacheEvict

@CacheConfig

Cache注解都需要提供Cache名称,如果每个Service方法上都包含 Cache名称,可能写起来重复。
注解 CacheConfig作用于类上,可以为此类的方法的缓存注解提供默认值,包括:

  • 缓存的默认名称
  • 缓存的 KeyGenerator

使用 RedisCache

集成Redis缓存

pom

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

配置application.properties:

1
2
3
4
spring.cache.type=REDIS
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=Redis!123

禁止缓存

通常在开发环境下,不需要使用Redis类型的缓存,你可以配置为Simple,动切换,用HashMap作为缓存,或者使用None禁止缓存以方便开发。

定制缓存

对于 RedisCacheManager来说,还可以定制缓存项的存活时间,缓存名是否在Redis中加上前缀等,这是通过实现CacheManagerCustomizer配置来完成定制

Redis 缓存原理

SpringBoot的自动配直类RedisCacheConfiguration会自动检测 spring.cache.type的值,从而决定使用何种缓存。

实现Redis两级缓存

Powered by Hexo and Hexo-theme-hiker

Copyright © 2013 - 2021 朝着牛逼的道路一路狂奔 All Rights Reserved.

访客数 : | 访问量 :