Spring Boot集成cache

来源:互联网 发布:网络系统管理课程 编辑:程序博客网 时间:2024/06/07 04:52

缓存简介

工作机制是:先从缓存中读取数据,如果没有再从慢速设备上读取实际数据(数据也会存入缓存);缓存什么:那些经常读取且不经常修改的数据/那些昂贵(CPU/IO)的且对于相同的请求有相同的计算结果的数据。例如Maven/京东物流都是这种思想

缓存命中率

即从缓存中读取数据的次数 与 总读取次数的比率,命中率越高越好:

命中率 = 从缓存中读取次数 / (总读取次数[从缓存中读取次数 + 从慢速设备上读取的次数])

缓存策略

Eviction policy 移除策略,即如果缓存满了,从缓存中移除数据的策略;常见的有LFU、LRU、FIFO:

FIFO(First In First Out):先进先出算法,即先放入缓存的先被移除;

LRU(Least Recently Used):最久未使用算法,使用时间距离现在最久的那个被移除;

LFU(Least Frequently Used):最近最少使用算法,一定时间段内使用次数(频率)最少的那个被移除;

TTL(Time To Live )存活期,即从缓存中创建时间点开始直到它到期的一个时间段(不管在这个时间段内有没有访问都将过期)

TTI(Time To Idle)空闲期,即一个数据多久没被访问将从缓存中移除的时间。

spring定义了org.springframework.cache.CacheManager和org.springframework.cache.Cache接口来统一不同的缓存技术,而SpringBoot为我们提供了自动配置多个CacheManager的实现

EhCacheCacheConfiguration.class EhCache实现缓存

GuavaCacheConfiguration.class Guava实现缓存

JCacheCacheConfiguration.class JCache实现缓存

GenericCacheConfiguration.class Collection实现缓存

SimpleCacheConfiguration.class ConcurrentMap实现缓存

在不做任何额外配置的情况下,默认使用SimpleCacheConfiguration,即ConcurrentMapCacheManager。Springboot支持以“spring.cache”为前缀的属性来配置,如:

spring.cache.type=#ehcache,generic,redis,jcache等

spring.cache.cache-names=#缓存名称

spring.cache.ehcache.config= #ehcache配置文件地址

在Spring Boot中通过@EnableCaching注解自动化配置合适的缓存管理器(CacheManager),Spring Boot根据下面的顺序去侦测缓存提供者:

Generic

JCache (JSR-107)

EhCache 2.x

Hazelcast

Infinispan

Redis

Guava

Simple

除了按顺序侦测外,我们也可以通过配置属性spring.cache.type来强制指定。我们可以通过debug调试查看cacheManager对象的实例来判断当前使用了什么缓存。

默认的ConcurrentMapCacheManager使用步骤:

1. 引入pom.xml

org.springframework.boot

spring-boot-starter-cache

2. 在主类或configuration类中通过 @EnableCaching 开启缓存

3. @Cacheable 查询,首先检查缓存是否存在,如果有则直接从缓存取然后返回,若没有则查DB,并将结果(有值或空)添加数据到缓存中。缓存名称为people,缓存key为person的id属性

参数:

value、cacheNames:两个等同的参数(cacheNames为Spring 4新增,作为value的别名),用于指定缓存存储的集合名。由于Spring 4中新增了@CacheConfig,因此在Spring 3中原本必须有的value属性,也成为非必需项了

key:缓存对象存储在Map集合中的key值,非必需,缺省按照函数的所有参数组合作为key值,若自己配置需使用SpEL表达式,比如:@Cacheable(key = "#p0"):使用函数第一个参数作为缓存的key值,更多关于SpEL表达式的详细内容可参考官方文档

condition:缓存对象的条件,非必需,也需使用SpEL表达式,只有满足表达式条件的内容才会被缓存,默认缓存所有结果数据。比如:@Cacheable(key = "#p0", condition = "#p0.length() < 3"),表示只有当第一个参数的长度小于3的时候才会被缓存,若做此配置上面的AAA用户就不会被缓存。

4. @CachePut 插入或更新到DB后,检查缓存中是否有该key,有则更新,没有则新增。新增或更新的内容为接口的返回值,所以保存/更新接口必须有返回值。 若返回值为空,则缓存也会为空值。

参数:同上

5. @CacheEvict 表示从缓存people中删除key为id的数据

参数:除上述之外,还有2个。

allEntries:非必需,默认为false。当为true时,会移除所有数据

beforeInvocation:非必需,默认为false,会在调用方法之后移除数据。当为true时,会在调用方法之前移除数据。

ehcache使用步骤:

1. pom.xml引入依赖:

net.sf.ehcache

ehcache

2.8.3

2. 在src/main/resources目录下创建:ehcache.xml

xsi:noNamespaceSchemaLocation="ehcache.xsd">

maxEntriesLocalHeap="200"

timeToLiveSeconds="600">

或配置

spring.cache.type=ehcache

spring.cache.ehcache.config=classpath:config/another-config.xml

redis使用步骤:

1. pom.xml引入依赖:

org.springframework.boot

spring-boot-starter-redis

2. properties中配置redis端口等

3. 配置RedisCacheManager,RedisTemplate的bean,具体参考源码

综合说明:

1. spring cache是spring3.1就有的概念,通过AOP实现,提供注解方式,但由于是进程内的缓存,适合于单机,分布式环境下不适用。EhCache提供了集群环境下的缓存同步策略,但是同步依然需要一定的时间,短暂的缓存不一致依然存在。在一些要求高一致性(任何数据变化都能及时的被查询到)的系统和应用中,就不能再使用EhCache来解决了,这个时候使用集中式缓存是个不错的选择

2. redis是集中式缓存,通过上述注解方式使用redisCacheManager,则缓存数据存储在redis,保证分布式环境数据一致性。

实例源码: test1-cache