本地快取 Caffeine 整合和配置
Caffeine 是 Java 8 對 Google Guava 快取的重寫,是一個提供了近乎最佳命中率的高效能的快取庫。我們按照如下步驟整合和配置:
- 新增 spring-boot-starter-cache 依賴
使用 spring-boot-starter-cache “Starter” 可以快速新增基本快取依賴項。 starter 引入了 spring-context-support。如果我們手動新增依賴項,則必須包含 spring-context-support 才能使用 JCache 或 Caffeine 支援。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
- 新增 caffeine 依賴
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
- 自定義快取管理器
/**
* Caffeine 快取管理器
*/
@Bean
public CacheManager caffeineCacheManager() {
SimpleCacheManager cacheManager = new SimpleCacheManager();
List<CaffeineCache> caches = new ArrayList<>(CacheConsts.CacheEnum.values().length);
for (CacheConsts.CacheEnum c : CacheConsts.CacheEnum.values()) {
if (c.isLocal()) {
Caffeine<Object, Object> caffeine = Caffeine.newBuilder().recordStats().maximumSize(c.getMaxSize());
if (c.getTtl() > 0) {
caffeine.expireAfterWrite(Duration.ofSeconds(c.getTtl()));
}
caches.add(new CaffeineCache(c.getName(), caffeine.build()));
}
}
cacheManager.setCaches(caches);
return cacheManager;
}
- 使用 @EnableCaching 註解開啟快取
@SpringBootApplication
@MapperScan("io.github.xxyopen.novel.dao.mapper")
@EnableCaching
@Slf4j
public class NovelApplication {
public static void main(String[] args) {
SpringApplication.run(NovelApplication.class, args);
}
@Bean
public CommandLineRunner commandLineRunner(ApplicationContext context){
return args -> {
Map<String, CacheManager> beans = context.getBeansOfType(CacheManager.class);
log.info("載入瞭如下快取管理器:");
beans.forEach((k,v)->{
log.info("{}:{}",k,v.getClass().getName());
log.info("快取:{}",v.getCacheNames());
});
};
}
}
這樣我們就可以使用 Spring Cache 的註解(例如 @Cacheable)開發了。
分散式快取 Redis 整合和配置
本地快取雖然有著訪問速度快的優點,但無法進行大資料的儲存。並且當我們叢集部署多個服務節點,或者後期隨著業務發展進行服務拆分後,沒法共享快取和保證快取資料的一致性。
本地快取的資料還會隨應用程式的重啟而丟失,這樣對於需要持久化的資料滿足不了需求,還會導致重啟後資料庫瞬時壓力過大。
所以本地快取一般適合於快取只讀資料,如統計類資料,或者每個部署節點獨立的資料。其它情況就需要用到分散式快取了。
分散式快取的整合步驟和本地快取基本差不多,除了替換 caffeine 的依賴項為我們 redis 的依賴和配置上我們自定義的 redis 快取管理器外,還要在配置檔案中加入 redis 的連線配置:
- 加入依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
- 配置 redis 快取管理器
/**
* 快取配置類
*
* @author xiongxiaoyang
* @date 2022/5/12
*/
@Configuration
public class CacheConfig {
/**
* Caffeine 快取管理器
*/
@Bean
@Primary
public CacheManager caffeineCacheManager() {
SimpleCacheManager cacheManager = new SimpleCacheManager();
List<CaffeineCache> caches = new ArrayList<>(CacheConsts.CacheEnum.values().length);
for (CacheConsts.CacheEnum c : CacheConsts.CacheEnum.values()) {
if (c.isLocal()) {
Caffeine<Object, Object> caffeine = Caffeine.newBuilder().recordStats().maximumSize(c.getMaxSize());
if (c.getTtl() > 0) {
caffeine.expireAfterWrite(Duration.ofSeconds(c.getTtl()));
}
caches.add(new CaffeineCache(c.getName(), caffeine.build()));
}
}
cacheManager.setCaches(caches);
return cacheManager;
}
/**
* Redis 快取管理器
*/
@Bean
public CacheManager redisCacheManager(RedisConnectionFactory connectionFactory) {
RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig()
.disableCachingNullValues().prefixCacheNameWith(CacheConsts.REDIS_CACHE_PREFIX);
Map<String, RedisCacheConfiguration> cacheMap = new LinkedHashMap<>(CacheConsts.CacheEnum.values().length);
for (CacheConsts.CacheEnum c : CacheConsts.CacheEnum.values()) {
if (c.isRemote()) {
if (c.getTtl() > 0) {
cacheMap.put(c.getName(), RedisCacheConfiguration.defaultCacheConfig().disableCachingNullValues()
.prefixCacheNameWith(CacheConsts.REDIS_CACHE_PREFIX).entryTtl(Duration.ofSeconds(c.getTtl())));
} else {
cacheMap.put(c.getName(), RedisCacheConfiguration.defaultCacheConfig().disableCachingNullValues()
.prefixCacheNameWith(CacheConsts.REDIS_CACHE_PREFIX));
}
}
}
RedisCacheManager redisCacheManager = new RedisCacheManager(redisCacheWriter, defaultCacheConfig, cacheMap);
redisCacheManager.setTransactionAware(true);
redisCacheManager.initializeCaches();
return redisCacheManager;
}
}
- application.yml 中加入 redis 連線配置資訊
spring:
redis:
host: 127.0.0.1
port: 6379
password: 123456