登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

学无止境

一点积累,与大家分享

 
 
 

日志

 
 

memcached的使用(一)  

2010-08-09 14:35:43|  分类: java技术 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
一直在关注javaeye,但长期在潜水。javaeye改版后功能强多了,而且最近工作也变动了,接触了一些新东西,以后还是坚持在这里记录些东西吧,也非常看好javaeye的发展。
这些天在设计SNA的架构,接触了一些远程缓存、集群、session复制等的东西,以前做企业应用的时候感觉作用不大,现在设计面对internet的系统架构时就非常有用了,而且在调试后看到压力测试的情况还是比较爽的。
在缓存的选择上有过很多的思考,虽然说memcached结合java在序列化上性能不怎么样,不过也没有更好的集群环境下的缓存解决方案了,就 选择了memcached。本来计划等公司买的服务器到位装个linux再来研究memcached,但这两天在找到了一个windows下的 Memcached版本,就动手开始调整现有的框架了。

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

目标,对旧框架缓存部分进行改造:
1、缓存工具类
2、hibernate的provider
3、用缓存实现session机制

今天先研究研究缓存工具类的改造,在旧框架中部分函数用了ehcache对执行结果进行了缓存处理,现在目标是提供一个缓存工具类,在配置文件中 配置使用哪种缓存(memcached或ehcached),使其它程序对具体的缓存不依赖,同时使用AOP方式来对方法执行结果进行缓存。
首先是工具类的实现:
在Spring中配置
Java代码
  1. <!-- EhCache Manager -->  
  2. <bean id="cacheManager"  
  3.     class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">  
  4.     <property name="configLocation">  
  5.         <value>classpath:ehcache.xml</value>  
  6.     </property>  
  7. </bean>  
  8.   
  9. <bean id="localCache"  
  10.     class="org.springframework.cache.ehcache.EhCacheFactoryBean">  
  11.     <property name="cacheManager" ref="cacheManager" />  
  12.     <property name="cacheName"  
  13.         value="×××.cache.LOCAL_CACHE" />  
  14. </bean>  
  15.   
  16. <bean id="cacheService"  
  17.     class="×××.core.cache.CacheService" init-method="init" destroy-method="destory">  
  18.     <property name="cacheServerList" value="${cache.servers}"/>  
  19.     <property name="cacheServerWeights" value="${cache.cacheServerWeights}"/>  
  20.     <property name="cacheCluster" value="${cache.cluster}"/>  
  21.     <property name="localCache" ref="localCache"/>  
  22. </bean>  
	<!-- EhCache Manager -->
	<bean id="cacheManager"
		class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
		<property name="configLocation">
			<value>classpath:ehcache.xml</value>
		</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代码
  1. /** 
  2.  * @author Marc 
  3.  *  
  4.  */  
  5. public class CacheService {  
  6.     private Log logger = LogFactory.getLog(getClass());  
  7.   
  8.     private Cache localCache;  
  9.   
  10.     String cacheServerList;  
  11.   
  12.     String cacheServerWeights;  
  13.   
  14.     boolean cacheCluster = false;  
  15.   
  16.     int initialConnections = 10;  
  17.   
  18.     int minSpareConnections = 5;  
  19.   
  20.     int maxSpareConnections = 50;  
  21.   
  22.     long maxIdleTime = 1000 * 60 * 30// 30 minutes  
  23.   
  24.     long maxBusyTime = 1000 * 60 * 5// 5 minutes  
  25.   
  26.     long maintThreadSleep = 1000 * 5// 5 seconds  
  27.   
  28.     int socketTimeOut = 1000 * 3// 3 seconds to block on reads  
  29.   
  30.     int socketConnectTO = 1000 * 3// 3 seconds to block on initial  
  31.                                     // connections. If 0, then will use blocking  
  32.                                     // connect (default)  
  33.   
  34.     boolean failover = false// turn off auto-failover in event of server  
  35.                                 // down  
  36.   
  37.     boolean nagleAlg = false// turn off Nagle's algorithm on all sockets in  
  38.                                 // pool  
  39.   
  40.     MemCachedClient mc;  
  41.   
  42.     public CacheService(){  
  43.         mc = new MemCachedClient();  
  44.         mc.setCompressEnable(false);  
  45.     }  
  46.     /** 
  47.      * 放入 
  48.      *  
  49.      */  
  50.     public void put(String key, Object obj) {  
  51.         Assert.hasText(key);  
  52.         Assert.notNull(obj);  
  53.         Assert.notNull(localCache);  
  54.         if (this.cacheCluster) {  
  55.             mc.set(key, obj);  
  56.         } else {  
  57.             Element element = new Element(key, (Serializable) obj);  
  58.             localCache.put(element);  
  59.         }  
  60.     }  
  61.     /** 
  62.      * 删除  
  63.      */  
  64.     public void remove(String key){  
  65.         Assert.hasText(key);  
  66.         Assert.notNull(localCache);  
  67.         if (this.cacheCluster) {  
  68.             mc.delete(key);  
  69.         }else{  
  70.             localCache.remove(key);  
  71.         }  
  72.     }  
  73.     /** 
  74.      * 得到 
  75.      */  
  76.     public Object get(String key) {  
  77.         Assert.hasText(key);  
  78.         Assert.notNull(localCache);  
  79.         Object rt = null;  
  80.         if (this.cacheCluster) {  
  81.             rt = mc.get(key);  
  82.         } else {  
  83.             Element element = null;  
  84.             try {  
  85.                 element = localCache.get(key);  
  86.             } catch (CacheException cacheException) {  
  87.                 throw new DataRetrievalFailureException("Cache failure: "  
  88.                         + cacheException.getMessage());  
  89.             }  
  90.             if(element != null)  
  91.                 rt = element.getValue();  
  92.         }  
  93.         return rt;  
  94.     }  
  95.     /** 
  96.      * 判断是否存在 
  97.      *  
  98.      */  
  99.     public boolean exist(String key){  
  100.         Assert.hasText(key);  
  101.         Assert.notNull(localCache);  
  102.         if (this.cacheCluster) {  
  103.             return mc.keyExists(key);  
  104.         }else{  
  105.             return this.localCache.isKeyInCache(key);  
  106.         }  
  107.     }  
  108.     private void init() {  
  109.         if (this.cacheCluster) {  
  110.             String[] serverlist = cacheServerList.split(",");  
  111.             Integer[] weights = this.split(cacheServerWeights);  
  112.             // initialize the pool for memcache servers  
  113.             SockIOPool pool = SockIOPool.getInstance();  
  114.             pool.setServers(serverlist);  
  115.             pool.setWeights(weights);  
  116.             pool.setInitConn(initialConnections);  
  117.             pool.setMinConn(minSpareConnections);  
  118.             pool.setMaxConn(maxSpareConnections);  
  119.             pool.setMaxIdle(maxIdleTime);  
  120.             pool.setMaxBusyTime(maxBusyTime);  
  121.             pool.setMaintSleep(maintThreadSleep);  
  122.             pool.setSocketTO(socketTimeOut);  
  123.             pool.setSocketConnectTO(socketConnectTO);  
  124.             pool.setNagle(nagleAlg);  
  125.             pool.setHashingAlg(SockIOPool.NEW_COMPAT_HASH);  
  126.             pool.initialize();  
  127.             logger.info("初始化memcached pool!");  
  128.         }  
  129.     }  
  130.   
  131.     private void destory() {  
  132.         if (this.cacheCluster) {  
  133.             SockIOPool.getInstance().shutDown();  
  134.         }  
  135.     }  
  136. }  
/**
 * @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("初始化memcached pool!");
		}
	}

	private void destory() {
		if (this.cacheCluster) {
			SockIOPool.getInstance().shutDown();
		}
	}
}

然后实现函数的AOP拦截类,用来在函数执行前返回缓存内容
Java代码
  1. public class CachingInterceptor implements MethodInterceptor {  
  2.   
  3.     private CacheService cacheService;  
  4.     private String cacheKey;  
  5.   
  6.     public void setCacheKey(String cacheKey) {  
  7.         this.cacheKey = cacheKey;  
  8.     }  
  9.   
  10.     public void setCacheService(CacheService cacheService) {  
  11.         this.cacheService = cacheService;  
  12.     }  
  13.   
  14.     public Object invoke(MethodInvocation invocation) throws Throwable {  
  15.         Object result = cacheService.get(cacheKey);  
  16.         //如果函数返回结果不在Cache中,执行函数并将结果放入Cache  
  17.         if (result == null) {  
  18.             result = invocation.proceed();  
  19.             cacheService.put(cacheKey,result);  
  20.         }  
  21.         return result;  
  22.     }  
  23. }  
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代码
  1. <aop:config proxy-target-class="true">  
  2.         <aop:advisor  
  3.             pointcut="execution(* ×××.PoiService.getOne(..))"  
  4.             advice-ref="PoiServiceCachingAdvice" />  
  5.     </aop:config>  
  6.   
  7.     <bean id="BasPoiServiceCachingAdvice"  
  8.         class="×××.core.cache.CachingInterceptor">  
  9.         <property name="cacheKey" value="PoiService" />  
  10.         <property name="cacheService" ref="cacheService" />  
  11.     </bean>
  评论这张
 
阅读(624)| 评论(0)

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018