使用 Redis + Caffeine 實現二級緩存可以有效提升應用的性能和緩存的命中率。Caffeine 是一個高效的 Java 本地緩存庫,而 Redis 是一個分布式緩存解決方案。通過將兩者結合,Caffeine 作為一級緩存用于快速訪問常用數據,Redis 作為二級緩存用于持久化存儲和共享。
下面是一個實現熱門文章二級緩存的示例步驟:
1. 添加依賴
在 pom.xml
中添加所需的依賴:
<dependencies><!-- Spring Boot dependencies --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency><dependency><groupId>com.github.ben-manes.caffeine</groupId><artifactId>caffeine</artifactId></dependency>
</dependencies>
2. 配置 Redis
在 application.properties
文件中配置 Redis:
spring.redis.host=localhost
spring.redis.port=6379
3. 配置緩存管理器
在 Spring Boot 應用中配置 Caffeine 和 Redis 的緩存管理器,并創建一個組合緩存管理器。
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.cache.interceptor.CacheErrorHandler;
import org.springframework.cache.interceptor.SimpleCacheErrorHandler;
import org.springframework.cache.redis.RedisCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;import java.time.Duration;
import java.util.Arrays;@Configuration
@EnableCaching
public class CacheConfig {@Beanpublic Caffeine<Object, Object> caffeineConfig() {return Caffeine.newBuilder().initialCapacity(100).maximumSize(500).expireAfterWrite(Duration.ofMinutes(10));}@Beanpublic CaffeineCacheManager caffeineCacheManager(Caffeine<Object, Object> caffeine) {CaffeineCacheManager cacheManager = new CaffeineCacheManager();cacheManager.setCaffeine(caffeine);return cacheManager;}@Beanpublic RedisCacheConfiguration redisCacheConfiguration() {return RedisCacheConfiguration.defaultCacheConfig().serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())).entryTtl(Duration.ofHours(1));}@Beanpublic RedisCacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory, RedisCacheConfiguration redisCacheConfiguration) {return RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(redisCacheConfiguration).build();}@Beanpublic CacheManager cacheManager(CaffeineCacheManager caffeineCacheManager, RedisCacheManager redisCacheManager) {return new CompositeCacheManager(caffeineCacheManager, redisCacheManager);}@Beanpublic CacheErrorHandler errorHandler() {return new SimpleCacheErrorHandler();}
}
4. 創建服務類
創建一個服務類來處理熱門文章的緩存邏輯:
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;import java.util.List;@Service
public class ArticleService {@Cacheable(value = "hotArticles", key = "'hotArticles'")public List<Article> getHotArticles() {// 這里應從數據庫中獲取熱門文章return fetchHotArticlesFromDatabase();}private List<Article> fetchHotArticlesFromDatabase() {// 模擬數據庫查詢// 實際實現中應從數據庫或其他數據源獲取熱門文章return List.of(new Article(1, "Title1", "Content1"),new Article(2, "Title2", "Content2"),new Article(3, "Title3", "Content3"));}
}
5. 創建文章類
創建一個簡單的 Article
類:
public class Article {private int id;private String title;private String content;// Constructors, getters and setterspublic Article(int id, String title, String content) {this.id = id;this.title = title;this.content = content;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}
}
6. 啟用緩存
在主應用類中啟用緩存:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}
}
7. 測試緩存功能
創建一個簡單的控制器來測試緩存功能:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;@RestController
public class ArticleController {@Autowiredprivate ArticleService articleService;@GetMapping("/hot-articles")public List<Article> getHotArticles() {return articleService.getHotArticles();}
}
8. 啟動應用
啟動 Spring Boot 應用,并訪問 http://localhost:8080/hot-articles
來測試緩存功能。第一次訪問會從數據庫獲取數據,并緩存到 Caffeine 和 Redis。隨后的訪問會從 Caffeine 緩存中獲取數據,直到 Caffeine 緩存過期后再從 Redis 緩存中獲取數據。
通過這種方式,實現 Redis 和 Caffeine 的二級緩存,既提高了數據訪問速度,又保證了數據的持久化和一致性。