Spring boot 整合 ehcache 2.x 3.x -本地缓存以及持久化实现
文章目录
- 基本概念
- 数据存储
- Spring boot 2.x - ehcache 2.x
- pom
- ehcache.xml
- 配置
- 使用
- Spring boot 3.x - ehcache 3.x
- pom
- 配置
- 使用
基本概念
Ehcache 是一种基于标准的开源缓存,可提高性能、减轻数据库负担并简化可扩展性。它是使用最广泛的基于 Java 的缓存,因为它功能强大、成熟、功能齐全,并与其他流行的库和框架集成。Ehcache 从进程内缓存扩展到具有
TB 级
缓存的混合进程内/进程外部署
数据存储
Ehcache 采用
heap(堆内存)
、off-heap(堆外内存)
、disk(磁盘)
三级存储实现容量和性能的平衡,数据流动遵循分层淘汰和逐级回填的规则
Spring boot 2.x - ehcache 2.x
pom
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<!--本地缓存-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- 这里会自动拉取spring boot2.7.5 整合对应的版本 -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
updateCheck="false">
<diskStore path="user.dir" />
<!--
defaultCache:默认的缓存配置信息,如果不加特殊说明,则所有对象按照此配置项处理
maxElementsInMemory:设置了缓存的上限,最多存储多少个记录对象
eternal:代表对象是否永不过期
overflowToDisk:当内存中Element数量达到maxElementsInMemory时,Ehcache将会Element写到磁盘中
-->
<defaultCache
maxElementsInMemory="2000"
maxElementsOnDisk="10000"
diskPersistent="true"
eternal="true"
overflowToDisk="true"/>
<!--
maxElementsInMemory设置成1,overflowToDisk设置成true,只要有一个缓存元素,就直接存到硬盘上去
eternal设置成true,代表对象永久有效
maxElementsOnDisk设置成0 表示硬盘中最大缓存对象数无限大
diskPersistent设置成true表示缓存虚拟机重启期数据
-->
<cache
name="all_ds"
maxElementsInMemory="2000"
eternal="true"
overflowToDisk="true"
maxElementsOnDisk="10000"
diskPersistent="true"/>
</ehcache>
配置
import com.constant.CommonConstants;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableCaching
public class CacheConfig {
@Bean
public CacheManager cacheManager() {
EhCacheManagerFactoryBean cacheManager = new EhCacheManagerFactoryBean();
cacheManager.setShared(true);
cacheManager.setCacheManagerName(CommonConstants.DS_KEY);
return new EhCacheCacheManager(cacheManager.getObject());
}
}
@SpringBootApplication
public class Application {
public static void main(String[] args) {
//这里设置此环境变量,回在项目stop时,把数据输出到disk, 会在目录生成 .data 、.index 文件
System.setProperty(net.sf.ehcache.CacheManager.ENABLE_SHUTDOWN_HOOK_PROPERTY, "true");
SpringApplication.run(Application.class,args);
}
}
使用
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
@Resource
private CacheManager cacheManager;
Cache cache = cacheManager.getCache(DS_KEY);
Map<String,DataSourceConf> sourceConfMap = cache.get(DS_KEY, Map.class);
if (CollectionUtil.isEmpty(sourceConfMap)){
sourceConfMap = new ConcurrentHashMap<>();
}
sourceConfMap.put(conf.getDsName(),conf);
cache.put(DS_KEY,sourceConfMap);
Spring boot 3.x - ehcache 3.x
spring boot 3.x (3.4.1)通过
spring-boot-starter-cache
,整合ehcache 3.10.8 ,读数据时会有序列化问题(jdk9 模块化,反序列化失败),无法持久化存储.
这里采用原生方式集成,直接copy官网持久化示例
pom
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.4.1</version>
<relativePath/>
</parent>
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.10.8</version>
</dependency>
配置
import org.ehcache.CacheManager;
import org.ehcache.config.builders.CacheConfigurationBuilder;
import org.ehcache.config.builders.CacheManagerBuilder;
import org.ehcache.config.builders.ResourcePoolsBuilder;
import org.ehcache.config.units.EntryUnit;
import org.ehcache.config.units.MemoryUnit;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.io.File;
import java.util.LinkedList;
/**
* eehcahe 缓存、持久化配置
* @author xiaoshu
*/
@Configuration
public class EhcacheConfig {
@Bean
public CacheManager cacheManager() {
//缓存key名称
String cacheName = "ehcache";
return CacheManagerBuilder.newCacheManagerBuilder()
.with(CacheManagerBuilder.persistence(new File(bastPath(), "run_data")))
.withCache(cacheName,
CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, LinkedList.class,
ResourcePoolsBuilder.newResourcePoolsBuilder()
.heap(200, EntryUnit.ENTRIES)
.offheap(500, MemoryUnit.MB)
.disk(1, MemoryUnit.GB, true)
)
).build(true);
}
private String bastPath() {
File file = new File("");
return file.getAbsolutePath();
}
}
使用
Cache<String, LinkedList> cache = cacheManager.getCache(DS_KEY, String.class, LinkedList.class);
LinkedList<DsInfo> dsInfos = cache.get(DS_KEY);
if (CollectionUtil.isEmpty(dsInfos)){
dsInfos = new LinkedList<>();
}
dsInfos.add(dbBase.getDsInfo());
cache.put(DS_KEY,dsInfos);
项目启动会生成持久化目录