cache策略(四)oscache
oscache的实现,一个是实现cache接口,一个是实现provider接口,这样就可以配置在
cacheManager中使用了,其实其他的cache也可以参考这个实现来做
OSCache.java 如下:
package com.sillycat.easyview.plugin.cache.oscache;
import java.util.Date;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.opensymphony.oscache.base.NeedsRefreshException;
import com.opensymphony.oscache.general.GeneralCacheAdministrator;
import com.sillycat.easyview.plugin.cache.base.Cache;
import com.sillycat.easyview.plugin.cache.base.Timestamper;
import com.sillycat.easyview.plugin.commons.exceptions.CacheException;
/**
* OSCache 的代理实现
*/
public class OSCache implements Cache {
private static final Log log = LogFactory.getLog(OSCache.class);
private final int refreshPeriod;
private final String cron;
private final String regionName;
private GeneralCacheAdministrator cache = new GeneralCacheAdministrator();
private String toString(Object key) {
return String.valueOf(key) + '.' + regionName;
}
public OSCache(int refreshPeriod, String cron, String region) {
this.refreshPeriod = refreshPeriod;
this.cron = cron;
this.regionName = region;
}
public void setCacheCapacity(int cacheCapacity) {
cache.setCacheCapacity(cacheCapacity);
}
/**
* oscache 如果 get到的值为过期的话,则一定要cancelUpdate,否则线程会一直等待其它的线程将数据更新
*/
public Object get(Object key) throws CacheException {
try {
Object obj = cache.getFromCache(toString(key), refreshPeriod, cron);
return obj;
} catch (NeedsRefreshException e) {
if (log.isDebugEnabled()) {
log.debug(
"error then get:" + key + " from cache:" + regionName,
e);
}
cache.cancelUpdate(toString(key));
return null;
}
}
public Object read(Object key) throws CacheException {
return get(key);
}
public void update(Object key, Object value) throws CacheException {
put(key, value);
}
public void put(Object key, Object value) throws CacheException {
cache.putInCache(toString(key), value);
}
public void remove(Object key) throws CacheException {
cache.flushEntry(toString(key));
}
public void clear() throws CacheException {
cache.flushAll(new Date(System.currentTimeMillis() - 200));
}
public void destroy() throws CacheException {
cache.destroy();
}
public void lock(Object key) throws CacheException {
// local cache, so we use synchronization
}
public void unlock(Object key) throws CacheException {
// local cache, so we use synchronization
}
public long nextTimestamp() {
return Timestamper.next();
}
public int getTimeout() {
return Timestamper.ONE_MS * 60000; // ie. 60 seconds
}
public String getRegionName() {
return regionName;
}
public long getSizeInMemory() {
return -1;
}
public long getElementCountInMemory() {
return -1;
}
public long getElementCountOnDisk() {
return -1;
}
public Map toMap() {
throw new UnsupportedOperationException();
}
public String toString() {
return "OSCache(" + regionName + ')';
}
}
OsCacheProvider.java如下:
package com.sillycat.easyview.plugin.cache.oscache;
import java.io.InputStream;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import com.sillycat.easyview.plugin.cache.base.Cache;
import com.sillycat.easyview.plugin.cache.base.CacheProvider;
import com.sillycat.easyview.plugin.cache.base.Timestamper;
import com.sillycat.easyview.plugin.cache.memcached.MemCacheProvider;
import com.sillycat.easyview.plugin.commons.exceptions.CacheException;
import com.sillycat.easyview.plugin.commons.utils.StringUtil;
public class OsCacheProvider implements CacheProvider {
private static final Log log = LogFactory.getLog(OsCacheProvider.class);
public static final String OSCACHE_REFRESH_PERIOD = "oscache.refresh.period";
public static final String OSCACHE_CRON = "oscache.cron";
public static final String OSCACHE_CAPACITY = "oscache.capacity";
public Properties getProperties() throws CacheException {
Properties props = new Properties();
String properties = props.getProperty("oscache.conf",
"oscache.properties");
props.setProperty("oscache.conf", properties);
Resource propertiesResource = new ClassPathResource(properties);
try {
if (!propertiesResource.exists()) {
throw new CacheException("not found '" + properties
+ "' in classpath!");
}
InputStream propertiesInputStream = propertiesResource
.getInputStream();
props.load(propertiesInputStream);
propertiesInputStream.close();
log.info("Loaded '" + properties + "' from "
+ propertiesResource.getFile().getAbsolutePath());
} catch (Exception e) {
throw new CacheException("fail to load/read '" + properties + "'",
e);
}
return props;
}
/**
* 创建一个新的CACHE
*
* @param region
* @param properties
*
* @return
*
* @throws CacheException
*/
public Cache buildCache(String region)
throws CacheException {
Properties properties = this.getProperties();
String refreshPeriod = properties.getProperty(OSCACHE_REFRESH_PERIOD);
int intRefeshPeriod = 100000;
if (StringUtil.isNotBlank(refreshPeriod)) {
// 刷新间隔
intRefeshPeriod = Integer.parseInt(refreshPeriod);
}
String cron = properties.getProperty(OSCACHE_CRON);
// 得到实际的新的CACHE
final OSCache cache = new OSCache(intRefeshPeriod, cron, region);
int capacity = 100;
String capacityStr = properties.getProperty(OSCACHE_CAPACITY);
if (StringUtil.isNotBlank(capacityStr)) {
// 容量
capacity = Integer.valueOf(capacityStr).intValue();
}
cache.setCacheCapacity(capacity);
return cache;
}
public long nextTimestamp() {
return Timestamper.next();
}
public void start() throws CacheException {
}
public void stop() {
}
}
oscache.properties文件是oscache的配置文件,可以配置更多的参数,可以参考OSCACHE官方文档:
oscache.refresh.period=100000
#oscache.cron=
oscache.capacity=100
oscache的实现,一个是实现cache接口,一个是实现provider接口,这样就可以配置在
cacheManager中使用了,其实其他的cache也可以参考这个实现来做
OSCache.java 如下:
package com.sillycat.easyview.plugin.cache.oscache;
import java.util.Date;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.opensymphony.oscache.base.NeedsRefreshException;
import com.opensymphony.oscache.general.GeneralCacheAdministrator;
import com.sillycat.easyview.plugin.cache.base.Cache;
import com.sillycat.easyview.plugin.cache.base.Timestamper;
import com.sillycat.easyview.plugin.commons.exceptions.CacheException;
/**
* OSCache 的代理实现
*/
public class OSCache implements Cache {
private static final Log log = LogFactory.getLog(OSCache.class);
private final int refreshPeriod;
private final String cron;
private final String regionName;
private GeneralCacheAdministrator cache = new GeneralCacheAdministrator();
private String toString(Object key) {
return String.valueOf(key) + '.' + regionName;
}
public OSCache(int refreshPeriod, String cron, String region) {
this.refreshPeriod = refreshPeriod;
this.cron = cron;
this.regionName = region;
}
public void setCacheCapacity(int cacheCapacity) {
cache.setCacheCapacity(cacheCapacity);
}
/**
* oscache 如果 get到的值为过期的话,则一定要cancelUpdate,否则线程会一直等待其它的线程将数据更新
*/
public Object get(Object key) throws CacheException {
try {
Object obj = cache.getFromCache(toString(key), refreshPeriod, cron);
return obj;
} catch (NeedsRefreshException e) {
if (log.isDebugEnabled()) {
log.debug(
"error then get:" + key + " from cache:" + regionName,
e);
}
cache.cancelUpdate(toString(key));
return null;
}
}
public Object read(Object key) throws CacheException {
return get(key);
}
public void update(Object key, Object value) throws CacheException {
put(key, value);
}
public void put(Object key, Object value) throws CacheException {
cache.putInCache(toString(key), value);
}
public void remove(Object key) throws CacheException {
cache.flushEntry(toString(key));
}
public void clear() throws CacheException {
cache.flushAll(new Date(System.currentTimeMillis() - 200));
}
public void destroy() throws CacheException {
cache.destroy();
}
public void lock(Object key) throws CacheException {
// local cache, so we use synchronization
}
public void unlock(Object key) throws CacheException {
// local cache, so we use synchronization
}
public long nextTimestamp() {
return Timestamper.next();
}
public int getTimeout() {
return Timestamper.ONE_MS * 60000; // ie. 60 seconds
}
public String getRegionName() {
return regionName;
}
public long getSizeInMemory() {
return -1;
}
public long getElementCountInMemory() {
return -1;
}
public long getElementCountOnDisk() {
return -1;
}
public Map toMap() {
throw new UnsupportedOperationException();
}
public String toString() {
return "OSCache(" + regionName + ')';
}
}
OsCacheProvider.java如下:
package com.sillycat.easyview.plugin.cache.oscache;
import java.io.InputStream;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import com.sillycat.easyview.plugin.cache.base.Cache;
import com.sillycat.easyview.plugin.cache.base.CacheProvider;
import com.sillycat.easyview.plugin.cache.base.Timestamper;
import com.sillycat.easyview.plugin.cache.memcached.MemCacheProvider;
import com.sillycat.easyview.plugin.commons.exceptions.CacheException;
import com.sillycat.easyview.plugin.commons.utils.StringUtil;
public class OsCacheProvider implements CacheProvider {
private static final Log log = LogFactory.getLog(OsCacheProvider.class);
public static final String OSCACHE_REFRESH_PERIOD = "oscache.refresh.period";
public static final String OSCACHE_CRON = "oscache.cron";
public static final String OSCACHE_CAPACITY = "oscache.capacity";
public Properties getProperties() throws CacheException {
Properties props = new Properties();
String properties = props.getProperty("oscache.conf",
"oscache.properties");
props.setProperty("oscache.conf", properties);
Resource propertiesResource = new ClassPathResource(properties);
try {
if (!propertiesResource.exists()) {
throw new CacheException("not found '" + properties
+ "' in classpath!");
}
InputStream propertiesInputStream = propertiesResource
.getInputStream();
props.load(propertiesInputStream);
propertiesInputStream.close();
log.info("Loaded '" + properties + "' from "
+ propertiesResource.getFile().getAbsolutePath());
} catch (Exception e) {
throw new CacheException("fail to load/read '" + properties + "'",
e);
}
return props;
}
/**
* 创建一个新的CACHE
*
* @param region
* @param properties
*
* @return
*
* @throws CacheException
*/
public Cache buildCache(String region)
throws CacheException {
Properties properties = this.getProperties();
String refreshPeriod = properties.getProperty(OSCACHE_REFRESH_PERIOD);
int intRefeshPeriod = 100000;
if (StringUtil.isNotBlank(refreshPeriod)) {
// 刷新间隔
intRefeshPeriod = Integer.parseInt(refreshPeriod);
}
String cron = properties.getProperty(OSCACHE_CRON);
// 得到实际的新的CACHE
final OSCache cache = new OSCache(intRefeshPeriod, cron, region);
int capacity = 100;
String capacityStr = properties.getProperty(OSCACHE_CAPACITY);
if (StringUtil.isNotBlank(capacityStr)) {
// 容量
capacity = Integer.valueOf(capacityStr).intValue();
}
cache.setCacheCapacity(capacity);
return cache;
}
public long nextTimestamp() {
return Timestamper.next();
}
public void start() throws CacheException {
}
public void stop() {
}
}
oscache.properties文件是oscache的配置文件,可以配置更多的参数,可以参考OSCACHE官方文档:
oscache.refresh.period=100000
#oscache.cron=
oscache.capacity=100