学习

使用 Redis 缓存 REST 服务

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

目标#

了解在 Spring 应用程序中使用 Redis 作为缓存的便捷性

议程#

在本课中,学生将学习

  • 缓存 RESTful 服务的基础知识
  • 如何使用 Spring Data Redis RedisCacheManager 使用 RedisCacheConfiguration 进行配置
  • 如何使用 @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();
  }

  // ...
}

The cacheManager 方法接受 RedisConnectionFactory 的实例。在其中,我们将配置我们的缓存以使用 Redis 键前缀,该前缀等于我们的应用程序的主包加一个句点,即 com.redislabs.edu.redi2read.。我们还将缓存条目的 TTL(“生存时间”)设置为 1 小时,并确保我们不缓存空值。在类级别,我们还使用注释 @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 前缀下创建键以存储搜索方法的缓存条目。您无需自己执行缓存维护。Spring 将拦截请求并检查缓存;如果缓存命中,它将返回其值。否则,如果缓存未命中,它将存储缓存的搜索方法的返回值,允许该方法像没有缓存一样执行。如果我们尝试请求 https://localhost:8080/api/books/search?q=java

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

在第一次请求中,我们得到 28 毫秒的响应时间

随后的响应持续返回 8 毫秒到 10 毫秒的范围