Let's Go!

03_Java环境下Memcached应用详解

上一篇 / 下一篇  2011-04-14 23:21:59 / 个人分类:经典转载

Java环境下Memcached应用详解

 

这里将介绍Java环境下Memcached应用,Memcached主要是集群环境下的缓存解决方案,希望本文对大家有所帮助。

  本文将对在Java环境下Memcached应用进行详细介绍。Memcached主要是集群环境下的缓存解决方案,可以运行在Java或者.NET平台上,这里我们主要讲的是Windows下的Memcached应用。

  这些天在设计SNA的架构,接触了一些远程缓存、集群、session复制等的东西,以前做企业应用的时候感觉作用不大,现在设计面对internet的系统架构时就非常有用了,而且在调试后看到压力测试的情况还是比较好的。

  在缓存的选择上有过很多的思考,虽然说memcached结合java在序列化上性能不怎么样,不过也没有更好的集群环境下的缓存解决方案了,就选择了memcached。本来计划等公司买的服务器到位装个linux再来研究memcached,但这两天在找到了一个windows下的Memcached版本,就动手开始调整现有的框架了。

  Windows下的Server端很简单,不用安装,双击运行后默认服务端口是11211,没有试着去更改端口,因为反正以后会用Unix版本,到时再记录安装步骤。下载客户端的JavaAPI包,接口非常简单,参考API手册上就有现成的例子。

  目标,对旧框架缓存部分进行改造:

  1、缓存工具类

  2、hibernate的provider

  3、用缓存实现session机制

  今天先研究研究缓存工具类的改造,在旧框架中部分函数用了ehcache对执行结果进行了缓存处理,现在目标是提供一个缓存工具类,在配置文件中配置使用哪种缓存(memcached或ehcached),使其它程序对具体的缓存不依赖,同时使用AOP方式来对方法执行结果进行缓存。

  首先是工具类的实现:

  在Spring中配置

  Java代码


<bean id="cacheManager"     
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">      
<property name="configLocation">      
<value>classpath:ehcache.xmlvalue>      
property>      
bean>      
 
<bean id="localCache"     
class="org.springframework.cache.ehcache.EhCacheFactoryBean">      
<property name="cacheManager" ref="cacheManager" />      
<property name="cacheName"     
value="×××.cache.LOCAL_CACHE" />      
bean>      
 
<bean id="cacheService"     
class="×××.core.cache.CacheService" init-method="init" destroy-method="destory">      
<property name="cacheServerList" value="${cache.servers}"/>      
<property name="cacheServerWeights" value="${cache.cacheServerWeights}"/>      
<property name="cacheCluster" value="${cache.cluster}"/>      
<property name="localCache" ref="localCache"/>      
bean>     
  
<bean id="cacheManager"  
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">  
<property name="configLocation">  
<value>classpath:ehcache.xmlvalue>  
property>  
bean>  
<bean id="localCache"  
class="org.springframework.cache.ehcache.EhCacheFactoryBean">  
<property name="cacheManager" ref="cacheManager" />  
<property name="cacheName"  
value="×××.cache.LOCAL_CACHE" />  
bean>  
 
<bean id="cacheService"  
class="×××.core.cache.CacheService" init-method="init" destroy-method="destory">  
<property name="cacheServerList" value="${cache.servers}"/>  
<property name="cacheServerWeights" value="${cache.cacheServerWeights}"/>  
<property name="cacheCluster" value="${cache.cluster}"/>  
<property name="localCache" ref="localCache"/>  
bean> 

  在properties文件中配置${cache.servers} ${cache.cacheServerWeights} ${cache.cluster}

  具体工具类的代码

  Java代码


/**    
* @author Marc    
*     
*/     
public class CacheService {      
private Log logger = LogFactory.getLog(getClass());      
private Cache localCache;      
String cacheServerList;      
String cacheServerWeights;      
boolean cacheCluster = false;      
int initialConnections = 10;      
int minSpareConnections = 5;      
int maxSpareConnections = 50;      
long maxIdleTime = 1000 * 60 * 30; // 30 minutes     
long maxBusyTime = 1000 * 60 * 5; // 5 minutes     
long maintThreadSleep = 1000 * 5; // 5 seconds     
int socketTimeOut = 1000 * 3; // 3 seconds to block on reads     
int socketConnectTO = 1000 * 3; // 3 seconds to block on initial     
// connections. If 0, then will use blocking     
// connect (default)     
boolean failover = false; // turn off auto-failover in event of server     
// down     
boolean nagleAlg = false; // turn off Nagle's algorithm on all sockets in     
// pool     
MemCachedClient mc;      
public CacheService(){      
mc = new MemCachedClient();      
mc.setCompressEnable(false);      
}      
/**    
* 放入    
*     
*/     
public void put(String keyObject obj) {      
Assert.hasText(key);      
Assert.notNull(obj);      
Assert.notNull(localCache);      
if (this.cacheCluster) {      
mc.set(key, obj);      
} else {      
Element element = new Element(key, (Serializable) obj);      
localCache.put(element);      
}      
}      
/**    
* 删除     
*/     
public void remove(String key){      
Assert.hasText(key);      
Assert.notNull(localCache);      
if (this.cacheCluster) {      
mc.delete(key);      
}else{      
localCache.remove(key);      
}      
}      
/**    
* 得到    
*/     
public Object get(String key) {      
Assert.hasText(key);      
Assert.notNull(localCache);      
Object rt = null;      
if (this.cacheCluster) {      
rt = mc.get(key);      
} else {      
Element element = null;      
try {      
element = localCache.get(key);      
} catch (CacheException cacheException) {      
throw new DataRetrievalFailureException("Cache failure: "     
+ cacheException.getMessage());      
}      
if(element != null)      
rt = element.getValue();      
}      
return rt;      
}      
/**    
* 判断是否存在    
*     
*/     
public boolean exist(String key){      
Assert.hasText(key);      
Assert.notNull(localCache);      
if (this.cacheCluster) {      
return mc.keyExists(key);      
}else{      
return this.localCache.isKeyInCache(key);      
}      
}      
private void init() {      
if (this.cacheCluster) {      
String[] serverlist = cacheServerList.split(",");      
Integer[] weights = this.split(cacheServerWeights);      
// initialize the pool for memcache servers     
SockIOPool pool = SockIOPool.getInstance();      
pool.setServers(serverlist);      
pool.setWeights(weights);      
pool.setInitConn(initialConnections);      
pool.setMinConn(minSpareConnections);      
pool.setMaxConn(maxSpareConnections);      
pool.setMaxIdle(maxIdleTime);      
pool.setMaxBusyTime(maxBusyTime);      
pool.setMaintSleep(maintThreadSleep);      
pool.setSocketTO(socketTimeOut);      
pool.setSocketConnectTO(socketConnectTO);      
pool.setNagle(nagleAlg);      
pool.setHashingAlg(SockIOPool.NEW_COMPAT_HASH);      
pool.initialize();      
logger.info("初始化memcached pool!");      
}      
}      
 
private void destory() {      
if (this.cacheCluster) {      
SockIOPool.getInstance().shutDown();      
}      
}      
}     
/**   
* @author Marc   
*    
*/  
public class CacheService {   
private Log logger = LogFactory.getLog(getClass());   
private Cache localCache;   
String cacheServerList;   
String cacheServerWeights;   
boolean cacheCluster = false;   
int initialConnections = 10;   
int minSpareConnections = 5;   
int maxSpareConnections = 50;   
long maxIdleTime = 1000 * 60 * 30; // 30 minutes   
long maxBusyTime = 1000 * 60 * 5; // 5 minutes   
long maintThreadSleep = 1000 * 5; // 5 seconds   
int socketTimeOut = 1000 * 3; // 3 seconds to block on reads   
int socketConnectTO = 1000 * 3; // 3 seconds to block on initial   
// connections. If 0, then will use blocking   
// connect (default)   
boolean failover = false; // turn off auto-failover in event of server   
// down   
boolean nagleAlg = false; // turn off Nagle's algorithm on all sockets in   
// pool   
MemCachedClient mc;   
public CacheService(){   
mc = new MemCachedClient();   
mc.setCompressEnable(false);   
}   
/**   
* 放入   
*    
*/  
public void put(String key, Object obj) {   
Assert.hasText(key);   
Assert.notNull(obj);   
Assert.notNull(localCache);   
if (this.cacheCluster) {   
mc.set(key, obj);   
} else {   
Element element = new Element(key, (Serializable) obj);   
localCache.put(element);   
}   
}   
/**   
* 删除    
*/  
public void remove(String key){   
Assert.hasText(key);   
Assert.notNull(localCache);   
if (this.cacheCluster) {   
mc.delete(key);   
}else{   
localCache.remove(key);   
}   
}   
/**   
* 得到   
*/  
public Object get(String key) {   
Assert.hasText(key);   
Assert.notNull(localCache);   
Object rt = null;   
if (this.cacheCluster) {   
rt = mc.get(key);   
} else {   
Element element = null;   
try {   
element = localCache.get(key);   
} catch (CacheException cacheException) {   
throw new DataRetrievalFailureException("Cache failure: "  
+ cacheException.getMessage());   
}   
if(element != null)   
rt = element.getValue();   
}   
return rt;   
}   
/**   
* 判断是否存在   
*    
*/  
public boolean exist(String key){   
Assert.hasText(key);   
Assert.notNull(localCache);   
if (this.cacheCluster) {   
return mc.keyExists(key);   
}else{   
return this.localCache.isKeyInCache(key);   
}   
}   
private void init() {   
if (this.cacheCluster) {   
String[] serverlist = cacheServerList.split(",");   
Integer[] weights = this.split(cacheServerWeights);   
// initialize the pool for memcache servers   
SockIOPool pool = SockIOPool.getInstance();   
pool.setServers(serverlist);   
pool.setWeights(weights);   
pool.setInitConn(initialConnections);   
pool.setMinConn(minSpareConnections);   
pool.setMaxConn(maxSpareConnections);   
pool.setMaxIdle(maxIdleTime);   
pool.setMaxBusyTime(maxBusyTime);   
pool.setMaintSleep(maintThreadSleep);   
pool.setSocketTO(socketTimeOut);   
pool.setSocketConnectTO(socketConnectTO);   
pool.setNagle(nagleAlg);   
pool.setHashingAlg(SockIOPool.NEW_COMPAT_HASH);   
pool.initialize();   
logger.info("初始化memcachedpool!");   
}   
}   
private void destory() {   
if (this.cacheCluster) {   
SockIOPool.getInstance().shutDown();   
}   
}   

  然后实现函数的AOP拦截类,用来在函数执行前返回缓存内容

  Java代码


public class CachingInterceptor implements MethodInterceptor {      
 
private CacheService cacheService;      
private String cacheKey;      
 
public void setCacheKey(String cacheKey) {      
this.cacheKey = cacheKey;      
}      
 
public void setCacheService(CacheService cacheService) {      
this.cacheService = cacheService;      
}      
 
public Object invoke(MethodInvocation invocation) throws Throwable {      
Object result = cacheService.get(cacheKey);      
//如果函数返回结果不在Cache中,执行函数并将结果放入Cache     
if (result == null) {      
result = invocation.proceed();      
cacheService.put(cacheKey,result);      
}      
return result;      
}      
}     
public class CachingInterceptor implements MethodInterceptor {   
 
private CacheService cacheService;   
private String cacheKey;   
 
public void setCacheKey(String cacheKey) {   
this.cacheKey = cacheKey;   
}   
 
public void setCacheService(CacheService cacheService) {   
this.cacheService = cacheService;   
}   
 
public Object invoke(MethodInvocation invocation) throws Throwable {   
Object result = cacheService.get(cacheKey);   
//如果函数返回结果不在Cache中,执行函数并将结果放入Cache   
if (result == null) {   
result = invocation.proceed();   
cacheService.put(cacheKey,result);   
}   
return result;   
}   

  Spring的AOP配置如下:

  Java代码


<aop:config proxy-target-class="true">      
<aop:advisor      
pointcut="execution(* ×××.PoiService.getOne(..))"     
advice-ref="PoiServiceCachingAdvice" />      
aop:config>      
 
<bean id="BasPoiServiceCachingAdvice"     
class="×××.core.cache.CachingInterceptor">      
<property name="cacheKey" value="PoiService" />      
<property name="cacheService" ref="cacheService" />      
bean>  

 

转自:http://webservices.ctocio.com.cn/java/270/9189770.shtml


TAG:

 

评分:0

我来说两句

Open Toolbar