最近在做一个报表任务开发,功能虽然简单,考虑到xml加载复杂耗时的情况下,引入缓存,由于万恶的客户不允许在其服务器上部署redis等内存数据库,搜索了网上一些基于java的缓存组件。最终选定apache 的jCS缓存组件来实现
先来段在网络上对于jcs的解释:
JCS是Jakarta的项目Turbine的子项目,它是复合式的缓冲工具,具有配置灵活的特点。JCS提供内存、硬盘、分布式架构、构建缓存服务器四种方式来实现对象缓存;能够很方便的实现缓存的差异化定制。缓冲工具对于读操作远远多于写操作的应用性能提高非常显著。
说白了 jcs 是基于配置文件 进行缓存,缓存机制可以基于 内存 和 disk rmi tcp甚至jdbc 实现复合缓存模型,以保证在有限的内存空间下利用其它的集中缓存方式缓存更多的数据。这其中我们可以认为内存是主缓存机制配合硬盘 分布式 远程 服务器或者jdbc 这些辅助缓存生成复合缓存模型。
1.概念:先了解jcs中的几个概念 element、region、auxiliary
1.element 对应jcs中存储数据对应的hashtable
2.region jcs缓存区域,通过配置region 将不同类数据分区域缓存
3.auxiliary 选择的辅助缓存的一些配置信息。
2.jcs使用
jcs的使用很简单,主要在配置,在根目录下创建jcs配置文件cache.css 然后基于jcs-1.3.jar 使用缓存服务
2.1 cache.css配置
cache.css 的配置 网络有很多说明 也可以参考官网说明http://commons.apache.org/proper/commons-jcs/ 。这里说明的事 配置中 可以先配置公共默认信息,如果要分类 可直接配置region信息 还有 auxiliary 配置 辅助缓存机制中的参数
2.2 jcs缓存实现
在配置完信息后,通过JCS.getInstance(String region)获得jcs缓存单例 其对应一个region中的hashtable
然后调用jcs.put(Object key,Object value) jcs.get(Object key)去存储或者查询 缓存对象。
贴上配置文件
#默认全局配置
jcs.default.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes
jcs.default.cacheattributes.MaxObjects=1000
jcs.default.cacheattributes.MemoryCacheName=org.apache.jcs.engine.memory.lru.LRUMemoryCache
jcs.default.cacheattributes.UseMemoryShrinker=true
jcs.default.cacheattributes.MaxMemoryIdleTimeSeconds=3600
jcs.default.cacheattributes.ShrinkerIntervalSeconds=600
jcs.default.cacheattributes.MaxSpoolPerRun=500
jcs.default.elementattributes=org.apache.jcs.engine.ElementAttributes
jcs.default.elementattributes.IsEternal=false
#report缓存区域配置
#添加辅助硬盘缓存
jcs.region.CONFIG=DC
jcs.region.CONFIG.elementattributes.MaxLifeSeconds=3600
#维度信息列表缓存区域配置
jcs.region.DIM=DC
#jcs.region.DIM.elementattributes.MaxLifeSeconds=43200
#INDEX DISK CACHE 硬盘索引辅助缓存配置
jcs.auxiliary.DC=org.apache.jcs.auxiliary.disk.indexed.IndexedDiskCacheFactory
jcs.auxiliary.DC.attributes=org.apache.jcs.auxiliary.disk.indexed.IndexedDiskCacheAttributes
jcs.auxiliary.DC.attributes.DiskPath=./reportCache
# 在内存中与磁盘缓存对象所对应的个数
jcs.auxiliary.DC.attributes.MaxPurgatorySize=10000
#### 设置key文件中缓冲对象个数
jcs.auxiliary.DC.attributes.MaxKeySize=10000
#### 删除处理的次数超过300000后对数据文件进行整理
jcs.auxiliary.DC.attributes.OptimizeAtRemoveCount=300000
jcs.auxiliary.DC.attributes.OptimizeOnShutdown=true
#### 保留key文件中已在data文件被删除对象的个数,需要符合内存算法
jcs.auxiliary.DC.attributes.MaxRecycleBinSize=7500
缓存实现
package com.asiainfo.bi.report.framework.util.cache.impl.jcs;
import java.util.HashMap;
import java.util.Map;
import org.apache.jcs.JCS;
import org.apache.jcs.access.exception.CacheException;
import com.asiainfo.bi.report.framework.bean.RepConfiguration;
import com.asiainfo.bi.report.framework.util.cache.CacheSvr;
/**
*
* @see
* @author Hu
* @date 2015-3-2 上午10:08:21
* @version
* @desc TODO
*/
public class JcsCacheSvrImpl implements CacheSvr {
private static Map<String, JCS> cacheSvrMap = new HashMap<String, JCS>();
public JcsCacheSvrImpl() {
}
private synchronized static JCS createCacheSvr(String cacheName) {
JCS jcs = null;
jcs = cacheSvrMap.get(cacheName);
if (jcs == null) {
try {
jcs = JCS.getInstance(cacheName);
cacheSvrMap.put(cacheName, jcs);
} catch (CacheException e) {
e.printStackTrace();
throw new RuntimeException("缓存服务创建失败");
}
}
return jcs;
}
/**
*
*/
@Override
public <V> void setValue(String region, String key, V value) {
JCS jcs = null;
try {
jcs = createCacheSvr(region);
//String valStr = JSON.toJSONString(value);
jcs.put(key, value);
} catch (CacheException e) {
e.printStackTrace();
throw new RuntimeException("缓存服务存储失败...");
}
}
@Override
public <T> T getValue(String region, String key, Class<T> clazz) {
JCS jcs = createCacheSvr(region);
Object obj = jcs.get(key);
if(obj !=null){
//String valStr = (String) obj;
//return JSON.parseObject(valStr, clazz);
return (T) obj;
}
return null;
}
public static void main(String[] args) throws InterruptedException {
JcsCacheSvrImpl impl = new JcsCacheSvrImpl();
impl.setValue("CONFIG", "TEST01", "aaaa" );
impl.setValue("CONFIG", "test11", new RepConfiguration());
int seconds=0;
while(true){
System.out.println("##########当前时间为" + seconds +"秒###############");
System.out.println(impl.getValue("CONFIG", "TEST01", String.class));
System.out.println(impl.getValue("CONFIG", "test11", RepConfiguration.class));
Thread.sleep(10*1000);
seconds += 10;
}
}
}