接口被频繁调用响应速度慢怎么办?试试Spring Cache

当接口的调用量加剧的时候,往往会出现接口响应速度过慢无法满足业务需求的情况,这时候就要考虑采用spring的缓存抽象机制来优化接口的相应速度。从 version 3.1 开始,Spring Framework 支持透明地将缓存添加到现有的 Spring application 中。与交易支持类似,缓存抽象允许一致使用各种缓存解决方案,而对 code 的影响最小。从 Spring 4.1 开始,在JSR-107 注释和更多自定义选项的支持下,缓存抽象得到了显着改进。

一、首先我们需要再pom文件中引入相关的依赖

Spring官方在Spring boot的Starter中提供了Spring Framework 相关的缓存支持,所以在pom文件中直接导入即可。
在这里插入图片描述

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-cacheartifactId>
dependency>

二、使用声明式 annotation-based 缓存举例

@Cacheable("books")
public Book findBook(ISBN isbn) {...}

三、常用Spring Cache注解解析

@Cacheable annotation

正如 name 所暗示的那样,@Cacheable用于划分可缓存的方法 - 即,将结果存储到缓存中的方法,以便在后续调用(具有相同的 arguments)时,返回缓存中的 value 而不必实际返回执行方法。在最简单的形式中,annotation 声明需要与带注释的方法关联的缓存的 name:

@Cacheable(cacheNames="books")
public Book findBook(ISBN isbn) {...}

1、在上面的代码段中,方法findBook与名为books的缓存相关联。调用该方法的每个 time 时,都会检查缓存以查看调用是否已经执行且不必重复。虽然在大多数情况下,只声明了一个缓存,但 annotation 允许指定多个名称,以便使用多个缓存。在这种情况下,将在执行方法之前检查每个缓存 - 如果至少有一个缓存被命中,则将返回关联的 value:

@Cacheable(cacheNames={"books", "isbns"})
public Book findBook(ISBN isbn) {...}

2、由于高速缓存本质上是 key-value stores,默认key为cacheNames+方法所有的参数(前面提到了,后续调用具有相同的 arguments时才会返回缓存中的value),如果想自定义key,比如调用方法时某些参数的不同并不会影响方法的返回值结果,对于这种情况,@Cacheable annotation 允许用户通过其key属性指定 key 的生成方式。

@Cacheable(cacheNames="books", key="#isbn")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)

@Cacheable(cacheNames="books", key="#isbn.rawNumber")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)

@Cacheable(cacheNames="books", key="T(someType).hash(#isbn)")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)

乍一看,虽然两个boolean arguments 影响了书的发现方式,但它们对缓存没有用处。如果两个中只有一个重要而另一个不重要等等,对于这些情况,@Cacheable annotation 允许用户通过其key属性指定 key 的生成方式。
3、sync属性是一个boolean值,默认为false,该属性为false时表示该缓存在被访问时并不会锁定,可能出现同一时刻,多次调用该方法,会多次计算相同的 value,从而无法实现缓存的特殊情况。该属性为true时表明该key对应的缓存在不支持并发访问,当有一个线程忙于计算 value,而其他线程将被阻塞,直到缓存中的条目更新为止。
4、举其他资料显示,使用jmeter进行压力测试,使用缓存与不使用缓存分别循环请求2000次,使用缓存比不使用缓存响应速度提升50%以上;

@CachePut annotation

对于需要更新缓存而不干扰方法执行的情况,可以使用@CachePut annotation。也就是说,将始终执行该方法并将其结果放入缓存中(根据@CachePut选项)。它支持与@Cacheable相同的选项,应该用于缓存填充而不是方法流优化:

@CachePut(cacheNames="book", key="#isbn")
public Book updateBook(ISBN isbn, BookDescriptor descriptor)

@CacheEvict annotation

缓存抽象不仅允许缓存 store 的填充,还允许驱逐。此 process 对于从缓存中删除过时或未使用的数据非常有用。与@Cacheable相反,annotation @CacheEvict划分了执行缓存逐出的方法,即用作从缓存中删除数据的触发器的方法。就像它的兄弟一样,@CacheEvict需要指定一个(或多个)受操作影响的缓存,允许自定义缓存和 key 解析或条件被指定,但另外,features 一个额外的参数allEntries,表示 cache-wide 驱逐是否需要要执行而不只是一个条目(基于 key):

@CacheEvict(cacheNames="books", allEntries=true)
public void loadBooks(InputStream batch)

@Caching annotation

对于 example,有些情况需要指定相同类型的多个注释,例如@CacheEvict或@CachePut,因为不同缓存之间的条件或 key 表达式不同。 @Caching允许在同一方法上使用多个嵌套的@Cacheable,@CachePut和@CacheEvict:

@Caching(evict = { @CacheEvict("primary"), @CacheEvict(cacheNames="secondary", key="#p0") })
public Book importBooks(String deposit, Date date)

四、详细官方文档参考

SpringFramework之缓存抽象

你可能感兴趣的:(Spring)