学习

使用 Redis 缓存 REST 服务

Brian Sam-Bodden
作者
Brian Sam-Bodden, Redis 开发者布道师

目标#

了解在 Spring 应用中使用 Redis 作为缓存是多么容易

议程#

在本课程中,学生将学习

  • 缓存 RESTful 服务的入门知识
  • 如何使用 RedisCacheConfiguration 配置 Spring Data Redis RedisCacheManager
  • 如何使用 @Cacheable 注解将 REST 控制器响应标记为可缓存 如果您遇到困难:
  • 本课程的进度可在 redi2read github 仓库中找到: https://github.com/redis-developer/redi2read/tree/course/milestone-9

Spring-Redis 缓存秘籍#

在我们的 Spring Boot 应用中实现缓存

  • 配置 Redis 缓存管理器
  • 使用 @EnableCaching 注解启用应用范围的缓存

在主应用文件 (src/main/java/com/redislabs/edu/redi2read/Redi2readApplication.java) 中,按照所示添加 cacheManager 方法

@SpringBootApplication
@EnableCaching
public class Redi2readApplication {

  // ...

  @Bean
  public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
    RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig() //
        .prefixCacheNameWith(this.getClass().getPackageName() + ".") //
        .entryTtl(Duration.ofHours(1)) //
        .disableCachingNullValues();

    return RedisCacheManager.builder(connectionFactory) //
        .cacheDefaults(config) //
        .build();
  }

  // ...
}

cacheManager 方法接受一个 RedisConnectionFactory 实例。在该方法中,我们将配置缓存使用等于应用主包加上一个点的 Redis key 前缀,即 com.redislabs.edu.redi2read.。我们还将缓存条目的 TTL 或“生存时间”设置为 1 小时,并确保不缓存 null 值。在类级别,我们还使用注解 @EnableCaching 来全局启用应用的缓存。上述更改需要下方所示的导入语句

import org.springframework.cache.annotation.EnableCaching;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import java.time.Duration;

使用 @Cacheable 注解#

在 RESTful 服务的上下文中,在应用和 HTTP 协议之间的交接点进行缓存是合理的。在一个由 Redis 提供支持的应用中考虑缓存任何东西似乎有点傻,但涉及许多数据仓库并执行密集计算的复杂业务逻辑会增加响应延迟。进行这种缓存的理想位置是在控制器级别。例如,假设我们想在 BookController 中缓存图书搜索的响应。我们可以简单地添加 @Cacheable 注解,如下所示

@GetMapping("/search")
@Cacheable("book-search")
public SearchResults<String,String> search(@RequestParam(name="q")String query) {
  RediSearchCommands<String, String> commands = searchConnection.sync();
  SearchResults<String, String> results = commands.search(searchIndexName, query);
  return results;
}

Spring 现在将使用 Redis 在 com.redislabs.edu.redi2read.book-search 前缀下创建 key,以存储搜索方法的缓存条目。您无需自行维护缓存。Spring 将拦截请求并检查缓存;如果缓存命中,它将返回缓存值。否则,如果缓存未命中,它将存储缓存搜索方法的返回值,从而允许该方法执行,就像没有缓存一样。如果我们尝试请求 http://localhost:8080/api/books/search?q=java

curl --location --request GET 'http://localhost:8080/api/books/search?q=java'

第一次请求的响应时间为 28 毫秒

后续响应持续稳定在 8 毫秒到 10 毫秒之间