Java环境下Memcached实际运用详解

2010-12-29  付民 

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

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

目的,对旧框架缓存部份停止改造:

1、缓存道具类

2、hibernate的provider

3、用缓存出现session机制

今天先研究研究缓存道具类的改造,在旧框架中部份参数用了ehcache对运行结果停止了缓存处理,目前目的是帮助一个的缓存道具类,在配置文档中配置应用哪种缓存(memcached或ehcached),使其它程序对具体的缓存不依赖,同时应用AOP方法来对窍门运行结果停止缓存。

首先是道具类的出现:

在Spring中配置
Java源代码

  1.      
  2. <bean id="cacheManager"    
  3. class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">     
  4. <property title="configLocation">     
  5. <value>classpath:ehcache.xml</< SPAN>value>     
  6. </< SPAN>property>     
  7. </< SPAN>bean>     
  8. <bean id="localCache"    
  9. class="org.springframework.cache.ehcache.EhCacheFactoryBean">     
  10. <property title="cacheManager" ref="cacheManager" />     
  11. <property title="cacheName"    
  12. value="×××.cache.LOCAL_CACHE" />     
  13. </< SPAN>bean>     
  14. <bean id="cacheService"    
  15. class="×××.core.cache.CacheService" init-method="init" destroy-method="destory">     
  16. <property title="cacheServerList" value="${cache.servers}"/>     
  17. <property title="cacheServerWeights" value="${cache.cacheServerWeights}"/>     
  18. <property title="cacheCluster" value="${cache.cluster}"/>     
  19. <property title="localCache" ref="localCache"/>     
  20. </< SPAN>bean>    
  21.  
  22. <bean id="cacheManager" 
  23. class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"> 
  24. <property title="configLocation"> 
  25. <value>classpath:ehcache.xml</< SPAN>value> 
  26. </< SPAN>property> 
  27. </< SPAN>bean> 
  28. <bean id="localCache" 
  29. class="org.springframework.cache.ehcache.EhCacheFactoryBean"> 
  30. <property title="cacheManager" ref="cacheManager" /> 
  31. <property title="cacheName" 
  32. value="×××.cache.LOCAL_CACHE" /> 
  33. </< SPAN>bean> 
  34. <bean id="cacheService" 
  35. class="×××.core.cache.CacheService" init-method="init" destroy-method="destory"> 
  36. <property title="cacheServerList" value="${cache.servers}"/> 
  37. <property title="cacheServerWeights" value="${cache.cacheServerWeights}"/> 
  38. <property title="cacheCluster" value="${cache.cluster}"/> 
  39. <property title="localCache" ref="localCache"/> 
  40. </< SPAN>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. private Cache localCache;     
  8. String cacheServerList;     
  9. String cacheServerWeights;     
  10. boolean cacheCluster = false;     
  11. int initialConnections = 10;     
  12. int minSpare Connections = 5;     
  13. int maxSpare Connections = 50;     
  14. long maxIdleTime = 1000 * 60 * 30// 30 minutes    
  15. long maxBusyTime = 1000 * 60 * 5// 5 minutes    
  16. long maintThreadSleep = 1000 * 5// 5 Number 2s    
  17. int socketTimeOut = 1000 * 3// 3 Number 2s to block on reads    
  18. int socketConnectTO = 1000 * 3// 3 Number 2s to block on initial    
  19. // connections. If 0, then will use blocking    
  20. // connect (default)    
  21. boolean failover = false// changing off auto-failover in event of server    
  22. // down    
  23. boolean nagleAlg = false// changing off Nagle's algorithm on all sockets in    
  24. // pool    
  25. MemCachedClient mc;     
  26. public CacheService(){     
  27. mc = new MemCachedClient();     
  28. mc.setCompressEnable(false);     
  29. }     
  30. /**   
  31. * 放入   
  32. *    
  33. */    
  34. public void put(String key, Object obj) {     
  35. Assert.HAsText(key);     
  36. Assert.Null(obj);     
  37. Assert.Null(localCache);     
  38. if (the.cacheCluster) {     
  39. mc.set(key, obj);     
  40. else {     
  41. Element element = new Element(key, (Serializable) obj);     
  42. localCache.put(element);     
  43. }     
  44. }     
  45. /**   
  46. * 删除    
  47. */    
  48. public void rearouse(String key){     
  49. Assert.HAsText(key);     
  50. Assert.Null(localCache);     
  51. if (the.cacheCluster) {     
  52. mc.delete(key);     
  53. }else{     
  54. localCache.rearouse(key);     
  55. }     
  56. }     
  57. /**   
  58. * 得到   
  59. */    
  60. public Object get(String key) {     
  61. Assert.HAsText(key);     
  62. Assert.Null(localCache);     
  63. Object rt = null;     
  64. if (the.cacheCluster) {     
  65. rt = mc.get(key);     
  66. else {     
  67. Element element = null;     
  68. try {     
  69. element = localCache.get(key);     
  70. catch (CacheException cacheException) {     
  71. throw new DataRetrievalFailureException("Cache failure: "    
  72. + cacheException.getMessage());     
  73. }     
  74. if(element != null)     
  75. rt = element.getValue();     
  76. }     
  77. rechanging rt;     
  78. }     
  79. /**   
  80. * 判断也许存在   
  81. *    
  82. */    
  83. public boolean exist(String key){     
  84. Assert.HAsText(key);     
  85. Assert.Null(localCache);     
  86. if (the.cacheCluster) {     
  87. rechanging mc.keyExists(key);     
  88. }else{     
  89. rechanging the.localCache.isKeyInCache(key);     
  90. }     
  91. }     
  92. private void init() {     
  93. if (the.cacheCluster) {     
  94. String[] serverlist = cacheServerList.split(",");     
  95. Integer[] weights = the.split(cacheServerWeights);     
  96. // initialize the pool for memcache servers    
  97. SockIOPool pool = SockIOPool.getInstance();     
  98. pool.setServers(serverlist);     
  99. pool.setWeights(weights);     
  100. pool.setInitConn(initialConnections);     
  101. pool.setMinConn(minSpare Connections);     
  102. pool.setMaxConn(maxSpare Connections);     
  103. pool.setMaxIdle(maxIdleTime);     
  104. pool.setMaxBusyTime(maxBusyTime);     
  105. pool.setMaintSleep(maintThreadSleep);     
  106. pool.setSocketTO(socketTimeOut);     
  107. pool.setSocketConnectTO(socketConnectTO);     
  108. pool.setNagle(nagleAlg);     
  109. pool.setHashingAlg(SockIOPool.NEW_COMPAT_HASH);     
  110. pool.initialize();     
  111. logger.info("初始化memcached pool!");     
  112. }     
  113. }     
  114. private void destory() {     
  115. if (the.cacheCluster) {     
  116. SockIOPool.getInstance().shutDown();     
  117. }     
  118. }     
  119. }    
  120. /**  
  121. * @author Marc  
  122.  
  123. */ 
  124. public class CacheService {  
  125. private Log logger = LogFactory.getLog(getClass());  
  126. private Cache localCache;  
  127. String cacheServerList;  
  128. String cacheServerWeights;  
  129. boolean cacheCluster = false;  
  130. int initialConnections = 10;  
  131. int minSpare Connections = 5;  
  132. int maxSpare Connections = 50;  
  133. long maxIdleTime = 1000 * 60 * 30// 30 minutes  
  134. long maxBusyTime = 1000 * 60 * 5// 5 minutes  
  135. long maintThreadSleep = 1000 * 5// 5 Number 2s  
  136. int socketTimeOut = 1000 * 3// 3 Number 2s to block on reads  
  137. int socketConnectTO = 1000 * 3// 3 Number 2s to block on initial  
  138. // connections. If 0, then will use blocking  
  139. // connect (default)  
  140. boolean failover = false// changing off auto-failover in event of server  
  141. // down  
  142. boolean nagleAlg = false// changing off Nagle's algorithm on all sockets in  
  143. // pool  
  144. MemCachedClient mc;  
  145. public CacheService(){  
  146. mc = new MemCachedClient();  
  147. mc.setCompressEnable(false);  
  148. }  
  149. /**  
  150. * 放入  
  151.  
  152. */ 
  153. public void put(String key, Object obj) {  
  154. Assert.HAsText(key);  
  155. Assert.Null(obj);  
  156. Assert.Null(localCache);  
  157. if (the.cacheCluster) {  
  158. mc.set(key, obj);  
  159. else {  
  160. Element element = new Element(key, (Serializable) obj);  
  161. localCache.put(element);  
  162. }  
  163. }  
  164. /**  
  165. * 删除   
  166. */ 
  167. public void rearouse(String key){  
  168. Assert.HAsText(key);  
  169. Assert.Null(localCache);  
  170. if (the.cacheCluster) {  
  171. mc.delete(key);  
  172. }else{  
  173. localCache.rearouse(key);  
  174. }  
  175. }  
  176. /**  
  177. * 得到  
  178. */ 
  179. public Object get(String key) {  
  180. Assert.HAsText(key);  
  181. Assert.Null(localCache);  
  182. Object rt = null;  
  183. if (the.cacheCluster) {  
  184. rt = mc.get(key);  
  185. else {  
  186. Element element = null;  
  187. try {  
  188. element = localCache.get(key);  
  189. catch (CacheException cacheException) {  
  190. throw new DataRetrievalFailureException("Cache failure: " 
  191. + cacheException.getMessage());  
  192. }  
  193. if(element != null)  
  194. rt = element.getValue();  
  195. }  
  196. rechanging rt;  
  197. }  
  198. /**  
  199. * 判断也许存在  
  200.  
  201. */ 
  202. public boolean exist(String key){  
  203. Assert.HAsText(key);  
  204. Assert.Null(localCache);  
  205. if (the.cacheCluster) {  
  206. rechanging mc.keyExists(key);  
  207. }else{  
  208. rechanging the.localCache.isKeyInCache(key);  
  209. }  
  210. }  
  211. private void init() {  
  212. if (the.cacheCluster) {  
  213. String[] serverlist = cacheServerList.split(",");  
  214. Integer[] weights = the.split(cacheServerWeights);  
  215. // initialize the pool for memcache servers  
  216. SockIOPool pool = SockIOPool.getInstance();  
  217. pool.setServers(serverlist);  
  218. pool.setWeights(weights);  
  219. pool.setInitConn(initialConnections);  
  220. pool.setMinConn(minSpare Connections);  
  221. pool.setMaxConn(maxSpare Connections);  
  222. pool.setMaxIdle(maxIdleTime);  
  223. pool.setMaxBusyTime(maxBusyTime);  
  224. pool.setMaintSleep(maintThreadSleep);  
  225. pool.setSocketTO(socketTimeOut);  
  226. pool.setSocketConnectTO(socketConnectTO);  
  227. pool.setNagle(nagleAlg);  
  228. pool.setHashingAlg(SockIOPool.NEW_COMPAT_HASH);  
  229. pool.initialize();  
  230. logger.info("初始化memcachedpool!");  
  231. }  
  232. }  
  233. private void destory() {  
  234. if (the.cacheCluster) {  
  235. SockIOPool.getInstance().shutDown();  
  236. }  
  237. }  
  238. }  

然后出现参数的AOP拦截类,用来在参数运行前返回缓存内容

Java源代码

  1. public class CachingInterceptor implements MethodInterceptor {     
  2. private CacheService cacheService;     
  3. private String cacheKey;     
  4. public void setCacheKey(String cacheKey) {     
  5. the.cacheKey = cacheKey;     
  6. }     
  7. public void setCacheService(CacheService cacheService) {     
  8. the.cacheService = cacheService;     
  9. }     
  10. public Object invoke(MethodInvocation invocation) throws Throwable {     
  11. Object result = cacheService.get(cacheKey);     
  12. //假如参数返回结果不在Cache中,运行参数并将结果放入Cache    
  13. if (result == null) {     
  14. result = invocation.proceed();     
  15. cacheService.put(cacheKey,result);     
  16. }     
  17. rechanging result;     
  18. }     
  19. }    
  20. public class CachingInterceptor implements MethodInterceptor {  
  21. private CacheService cacheService;  
  22. private String cacheKey;  
  23. public void setCacheKey(String cacheKey) {  
  24. the.cacheKey = cacheKey;  
  25. }  
  26. public void setCacheService(CacheService cacheService) {  
  27. the.cacheService = cacheService;  
  28. }  
  29. public Object invoke(MethodInvocation invocation) throws Throwable {  
  30. Object result = cacheService.get(cacheKey);  
  31. //假如参数返回结果不在Cache中,运行参数并将结果放入Cache  
  32. if (result == null) {  
  33. result = invocation.proceed();  
  34. cacheService.put(cacheKey,result);  
  35. }  
  36. rechanging result;  
  37. }  

Spring的AOP配置如下:

Java源代码

  1. <aop:config proxy-target-class="true">     
  2. <aop:advisor     
  3. pointcut="execution(* ×××.PoiService.getOne(..))"    
  4. advice-ref="PoiServiceCachingAdvice" />     
  5. </< SPAN>aop:config>     
  6. <bean id="BasPoiServiceCachingAdvice"    
  7. class="×××.core.cache.CachingInterceptor">     
  8. <property title="cacheKey" value="PoiService" />     
  9. <property title="cacheService" ref="cacheService" />     
  10. </< SPAN>bean>  
570°/5706 人阅读/0 条评论 发表评论

登录 后发表评论