0
点赞
收藏
分享

微信扫一扫

Java环境下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代码



  1. <beanid="cacheManager"
  2. class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
  3. <propertyname="configLocation">
  4. <value>classpath:ehcache.xmlvalue>
  5. property>
  6. bean>

  7. <beanid="localCache"
  8. class="org.springframework.cache.ehcache.EhCacheFactoryBean">
  9. <propertyname="cacheManager" ref="cacheManager"/>
  10. <propertyname="cacheName"
  11. value="×××.cache.LOCAL_CACHE"/>
  12. bean>

  13. <beanid="cacheService"
  14. class="×××.core.cache.CacheService" init-method="init" destroy-method="destory">
  15. <propertyname="cacheServerList" value="${cache.servers}"/>
  16. <propertyname="cacheServerWeights" value="${cache.cacheServerWeights}"/>
  17. <propertyname="cacheCluster" value="${cache.cluster}"/>
  18. <propertyname="localCache" ref="localCache"/>
  19. bean>

  20. <beanid="cacheManager"
  21. class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
  22. <propertyname="configLocation">
  23. <value>classpath:ehcache.xmlvalue>
  24. property>
  25. bean>
  26. <beanid="localCache"
  27. class="org.springframework.cache.ehcache.EhCacheFactoryBean">
  28. <propertyname="cacheManager" ref="cacheManager"/>
  29. <propertyname="cacheName"
  30. value="×××.cache.LOCAL_CACHE"/>
  31. bean>

  32. <beanid="cacheService"
  33. class="×××.core.cache.CacheService" init-method="init" destroy-method="destory">
  34. <propertyname="cacheServerList" value="${cache.servers}"/>
  35. <propertyname="cacheServerWeights" value="${cache.cacheServerWeights}"/>
  36. <propertyname="cacheCluster" value="${cache.cluster}"/>
  37. <propertyname="localCache" ref="localCache"/>
  38. bean>


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

具体工具类的代码

Java代码


  1. /**
  2. * @author Marc
  3. *
  4. */
  5. publicclassCacheService {
  6. privateLog logger = LogFactory.getLog(getClass());
  7. privateCache localCache;
  8. String cacheServerList;
  9. String cacheServerWeights;
  10. booleancacheCluster =false;
  11. intinitialConnections = 10;
  12. intminSpareConnections = 5;
  13. intmaxSpareConnections = 50;
  14. longmaxIdleTime = 1000 * 60 * 30; // 30 minutes
  15. longmaxBusyTime = 1000 * 60 * 5; // 5 minutes
  16. longmaintThreadSleep = 1000 * 5; // 5 seconds
  17. intsocketTimeOut = 1000 * 3; // 3 seconds to block on reads
  18. intsocketConnectTO = 1000 * 3; // 3 seconds to block on initial
  19. // connections. If 0, then will use blocking
  20. // connect (default)
  21. booleanfailover =false; // turn off auto-failover in event of server
  22. // down
  23. booleannagleAlg =false; // turn off Nagle's algorithm on all sockets in
  24. // pool
  25. MemCachedClient mc;
  26. publicCacheService(){
  27. mc =newMemCachedClient();
  28. mc.setCompressEnable(false);
  29. }
  30. /**
  31. * 放入
  32. *
  33. */
  34. publicvoidput(String key, Object obj) {
  35. Assert.hasText(key);
  36. Assert.notNull(obj);
  37. Assert.notNull(localCache);
  38. if(this.cacheCluster) {
  39. mc.set(key, obj);
  40. }else{
  41. Element element =newElement(key, (Serializable) obj);
  42. localCache.put(element);
  43. }
  44. }
  45. /**
  46. * 删除
  47. */
  48. publicvoidremove(String key){
  49. Assert.hasText(key);
  50. Assert.notNull(localCache);
  51. if(this.cacheCluster) {
  52. mc.delete(key);
  53. }else{
  54. localCache.remove(key);
  55. }
  56. }
  57. /**
  58. * 得到
  59. */
  60. publicObject get(String key) {
  61. Assert.hasText(key);
  62. Assert.notNull(localCache);
  63. Object rt =null;
  64. if(this.cacheCluster) {
  65. rt = mc.get(key);
  66. }else{
  67. Element element =null;
  68. try{
  69. element = localCache.get(key);
  70. }catch(CacheException cacheException) {
  71. thrownewDataRetrieval("Cache failure: "
  72. + cacheException.getMessage());
  73. }
  74. if(element !=null)
  75. rt = element.getValue();
  76. }
  77. returnrt;
  78. }
  79. /**
  80. * 判断是否存在
  81. *
  82. */
  83. publicbooleanexist(String key){
  84. Assert.hasText(key);
  85. Assert.notNull(localCache);
  86. if(this.cacheCluster) {
  87. returnmc.keyExists(key);
  88. }else{
  89. returnthis.localCache.isKeyInCache(key);
  90. }
  91. }
  92. privatevoidinit() {
  93. if(this.cacheCluster) {
  94. String[] serverlist = cacheServerList.split(",");
  95. Integer[] weights =this.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(minSpareConnections);
  102. pool.setMaxConn(maxSpareConnections);
  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. privatevoiddestory() {
  115. if(this.cacheCluster) {
  116. SockIOPool.getInstance().shutDown();
  117. }
  118. }
  119. }
  120. /**
  121. * @author Marc
  122. *
  123. */
  124. publicclassCacheService {
  125. privateLog logger = LogFactory.getLog(getClass());
  126. privateCache localCache;
  127. String cacheServerList;
  128. String cacheServerWeights;
  129. booleancacheCluster =false;
  130. intinitialConnections = 10;
  131. intminSpareConnections = 5;
  132. intmaxSpareConnections = 50;
  133. longmaxIdleTime = 1000 * 60 * 30; // 30 minutes
  134. longmaxBusyTime = 1000 * 60 * 5; // 5 minutes
  135. longmaintThreadSleep = 1000 * 5; // 5 seconds
  136. intsocketTimeOut = 1000 * 3; // 3 seconds to block on reads
  137. intsocketConnectTO = 1000 * 3; // 3 seconds to block on initial
  138. // connections. If 0, then will use blocking
  139. // connect (default)
  140. booleanfailover =false; // turn off auto-failover in event of server
  141. // down
  142. booleannagleAlg =false; // turn off Nagle's algorithm on all sockets in
  143. // pool
  144. MemCachedClient mc;
  145. publicCacheService(){
  146. mc =newMemCachedClient();
  147. mc.setCompressEnable(false);
  148. }
  149. /**
  150. * 放入
  151. *
  152. */
  153. publicvoidput(String key, Object obj) {
  154. Assert.hasText(key);
  155. Assert.notNull(obj);
  156. Assert.notNull(localCache);
  157. if(this.cacheCluster) {
  158. mc.set(key, obj);
  159. }else{
  160. Element element =newElement(key, (Serializable) obj);
  161. localCache.put(element);
  162. }
  163. }
  164. /**
  165. * 删除
  166. */
  167. publicvoidremove(String key){
  168. Assert.hasText(key);
  169. Assert.notNull(localCache);
  170. if(this.cacheCluster) {
  171. mc.delete(key);
  172. }else{
  173. localCache.remove(key);
  174. }
  175. }
  176. /**
  177. * 得到
  178. */
  179. publicObject get(String key) {
  180. Assert.hasText(key);
  181. Assert.notNull(localCache);
  182. Object rt =null;
  183. if(this.cacheCluster) {
  184. rt = mc.get(key);
  185. }else{
  186. Element element =null;
  187. try{
  188. element = localCache.get(key);
  189. }catch(CacheException cacheException) {
  190. thrownewDataRetrieval("Cache failure: "
  191. + cacheException.getMessage());
  192. }
  193. if(element !=null)
  194. rt = element.getValue();
  195. }
  196. returnrt;
  197. }
  198. /**
  199. * 判断是否存在
  200. *
  201. */
  202. publicbooleanexist(String key){
  203. Assert.hasText(key);
  204. Assert.notNull(localCache);
  205. if(this.cacheCluster) {
  206. returnmc.keyExists(key);
  207. }else{
  208. returnthis.localCache.isKeyInCache(key);
  209. }
  210. }
  211. privatevoidinit() {
  212. if(this.cacheCluster) {
  213. String[] serverlist = cacheServerList.split(",");
  214. Integer[] weights =this.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(minSpareConnections);
  221. pool.setMaxConn(maxSpareConnections);
  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. privatevoiddestory() {
  234. if(this.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. this.cacheKey = cacheKey;
  6. }

  7. public void setCacheService(CacheService cacheService) {
  8. this.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. return result;
  18. }
  19. }
  20. public class CachingInterceptor implements MethodInterceptor {

  21. private CacheService cacheService;
  22. private String cacheKey;

  23. public void setCacheKey(String cacheKey) {
  24. this.cacheKey = cacheKey;
  25. }

  26. public void setCacheService(CacheService cacheService) {
  27. this.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. return result;
  37. }
  38. }


Spring的AOP配置如下:

Java代码


  1. <aop:configproxy-target-class="true">
  2. <aop:advisor
  3. pointcut="execution(* ×××.PoiService.getOne(..))"
  4. advice-ref="PoiServiceCachingAdvice"/>
  5. aop:config>

  6. <beanid="BasPoiServiceCachingAdvice"
  7. class="×××.core.cache.CachingInterceptor">
  8. <propertyname="cacheKey" value="PoiService"/>
  9. <propertyname="cacheService" ref="cacheService"/>
  10. bean>
举报

相关推荐

0 条评论