ehcache
。对比我们常用的缓存中间件Redis,ehcache在Java生态下也具有他适用场景。
借此机会,正好学习一下,系统中ehcache缓存框架的集成过程。
这里是我这边项目原先使用的依赖,如果不适用,可以参考其他文章引入的依赖
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-cacheartifactId>
<version>1.4.2.RELEASEversion>
dependency>
<dependency>
<groupId>net.sf.ehcachegroupId>
<artifactId>ehcache-coreartifactId>
<version>2.4.5version>
dependency>
查询方法上添加@Cacheable
,便可以达到缓存数据的目的。
@Override
@Cacheable(value = CacheConstants.MCCP_HIGHLOAD_GETHIGHLOAD45GCHAIN_DAY_CACHE,key = "#param.starttime+'_'+#param.endtime")
public List<Map<String, Object>> getHighload45GChain(HighloadParam param) {
return iHighloadPortraitMapper.getHighload45GChain(param);
}
ps: ctrl+鼠标,点击@Cacheable注解,可以看到该注解的两个常用参数value(cacheNames)和key,
value
是一个String类型的数组,可以指定多个,
key
一般是填你方法对应的参数,(注意key不能是对象,因为对象是变化的,可能导致缓存失效!)
//使用到的常量类
public class CacheConstants {
// 45G流量环比,5G分流比环比
public final static String MCCP_HIGHLOAD_GETHIGHLOAD45GCHAIN_DAY_CACHE = "highload_gethighload45gchain_day_cache";
}
/**
* 实体类
* 项目使用了swagger,没有集成的话,把@ApiModel,@ApiModelProperty去掉就行
* 注意,List city也是对象,缓存的key尽量避免使用。
*/
@ApiModel
public class HighloadParam implements Serializable {
@ApiModelProperty(name = "starttime",value = "2021-05-17",required = false)
private String starttime;
@ApiModelProperty(name = "endtime",value = "2021-07-05",required = false)
private String endtime;
@ApiModelProperty(name = "city",value = "地市",required = false)
private List<String> city;
@Override
public String toString() {
return "HighloadParam{" +
"starttime='" + starttime + '\'' +
", endtime='" + endtime + '\'' +
", city=" + city +
'}';
}
}
ehcache.xml
配置文件,这里提供通用模板。在项目的resources目录下新建ehcache文件夹,并创建ehcache.xml文件。
ehcache会将相关缓存数据存放在这个文件下。
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd" name="consumerCache"
maxBytesLocalDisk="1G">
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="10000"
maxElementsOnDisk="0"
eternal="true"
overflowToDisk="true"
diskPersistent="false"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
diskSpoolBufferSizeMB="50"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LFU"
/>
<cache name="highload_gethighload45gchain_day_cache" eternal="false"
maxElementsInMemory="1000"
overflowToDisk="true"
diskPersistent="false"
timeToIdleSeconds="0"
timeToLiveSeconds="1800"
memoryStoreEvictionPolicy="LRU" />
<cache name="xxxxxxx" eternal="false"
maxElementsInMemory="1000"
overflowToDisk="true"
diskPersistent="false"
timeToIdleSeconds="0"
timeToLiveSeconds="1800"
memoryStoreEvictionPolicy="LRU" />
ehcache>
该项目没有使用在启动类上使用注解的方式,开启ehcache的缓存注解声明,
而是采用spring配置的方式,来声明对应的bean,
在resources目录下创建applicationContext-ehcache.xml
文件,可以直接copy模板
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"
default-autowire="byName" default-lazy-init="false">
<description>Spring3.1原生EhCache缓存description>
<cache:annotation-driven cache-manager="ehCacheManager" />
<bean id="ehCacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"
p:cacheManager-ref="ehCacheManagerFactory" />
<bean id="ehCacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:ehcache/ehcache.xml" />
bean>
beans>
这里先介绍使用缓存的逻辑过程,看图说话。
总之,一句话,使用缓存就是除了第一次查询外,后面的查询都不直接查询数据库,提高查询速度。
查看项目日志进行验证,
第一次调用该方法,走数据库,日志有打印查询SQL;
第二次调用该方法,日志无SQL日志输出,访问页面响应速度变快。
@RestController
@RequestMapping(value = "/highload")
public class HighloadController {
@Autowired
private EhCacheManagerFactoryBean ehCacheManagerFactory;
@PostMapping("/testCache")
public R testCache(@RequestParam(name="key") String key,@RequestParam(name="val")String val) {
CacheManager cacheManager = ehCacheManagerFactory.getObject();
Cache cache = cacheManager.getCache(CacheConstants.MCCP_HIGHLOAD_GETHIGHLOAD45G_DAY_CACHE);
Element element = cache.get(key);
//缓存判断
if(element==null){
cache.put(new Element(key, val));
return R.success("cache首次进入");
}else{
System.out.println(element.getObjectValue());
return R.success(element.getObjectValue().toString(),"进来缓存了:");
}
}
}