EhCache 分布式下缓存对象的同步

版权声明:本文为博主原创文章,未经博主允许不得转载。

为了提升目前开发产品的性能,项目组内考虑将一些常用的数据放入缓存,并且今后要将系统分布式部署,以达到负载均衡的目的,因此缓存同步问题就不得不需要考虑,该项目中主要用EhCache产品,EhCache的优势和劣势这里就不做介绍,网上可以搜索,单从这次项目出发,说说他在项目中的应用,hibernatespring都集成了EhCache,如果您的项目中用到这两个框架,那将会大大降低开发复杂度,如果没有使用此类框架,Ehcache还提供在项目中独立使用。

先大概了解一下EhCache的原理吧,见下图:

主要为三层,最上层的是CacheManager,它是操作Ehcache的入口。我们可以通过CacheManager.getInstance()(还有别的方法,可查看API)获得一个单例的CacheManger;每个CacheManager都管理着多个Cache;而每个Cache都以Hash的方式,关联着多个 Element;Element则是我们用于存放要缓存对象的地方。

先从EhCache在项目中独立使用的Demo说起:

开发环境:Eclipse4.0(不受限制)、JDK1.5;

引用Jar包:ehcache-core-2.5.2.jar

                   junit-3.8.1.jar

                  slf4j-api-1.6.1.jar

                  slf4j-jdk14-1.6.1.jar

新建一个Java Project,引入以上jar包,创建一个测试类TestPutElement,代码如下:

[java]  view plain  copy
  1. package ehcache;  
  2.   
  3. import java.net.URL;  
  4. import test.User;  
  5.   
  6. import junit.framework.TestCase;  
  7. import net.sf.ehcache.Cache;  
  8. import net.sf.ehcache.CacheManager;  
  9. import net.sf.ehcache.Element;  
  10.   
  11. public class TestPutElement extends TestCase {  
  12.       
  13.     public void testPut() throws Exception {  
  14.           
  15.         URL url = TestPutCache.class.getClassLoader().getResource(  
  16.                 "conf/ehcache.xml");  
  17.         CacheManager manager = new CacheManager(url);  
  18.           
  19.         Cache cache = manager.getCache("metaCache");  
  20.   
  21.         User user = new User();  
  22.         user.setName("张三");  
  23.         Element element = new Element("key",user);  
  24.         cache.put(element);  
  25.   
  26.         manager.shutdown();  
  27.         System.out.println("已放入缓存!");  
  28.     }  
  29. }  

创建一个POJO对象User,一定要经过序列化,并保证序列化UID的存在:

[java]  view plain  copy
  1. import java.io.Serializable;  
  2.   
  3. public class User implements Serializable {  
  4.   
  5.     private static final long serialVersionUID = -4402392412217726278L;  
  6.     private String name;  
  7.   
  8.     public String getName() {  
  9.         return name;  
  10.     }  
  11.   
  12.     public void setName(String name) {  
  13.         this.name = name;  
  14.     }  
  15. }  

在ClassPath目录下加入ehcache.xml文件,这也可以在Ehcachejar包中找到,有两个注意事项,不要删除defaultcache,如果是两台不同的电脑,那么把cacheManagerPeerProviderFactory中的第二个localhost换成另一台机器IP即可,端口号是可以自定义的,不过要注意不要和系统使用的端口冲突,不然会报错;

[html]  view plain  copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2.   
  3. <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.          xsi:noNamespaceSchemaLocation="ehcache.xsd"  
  5.          updateCheck="true" monitoring="autodetect"  
  6.          dynamicConfig="true">  
  7.   
  8.     <diskStore path="java.io.tmpdir" />  
  9.   
  10.     <!-- 指定除自身之外的网络群体中其他提供同步的主机列表,用“|”分开不同的主机 -->  
  11.     <cacheManagerPeerProviderFactory  
  12.         class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"  
  13.         properties="peerDiscovery=manual,rmiUrls=//localhost:40004/metaCache|//localhost:60000/metaCache" />  
  14.   
  15.     <!-- 配宿主主机配置监听程序,来发现其他主机发来的同步请求 -->  
  16.     <cacheManagerPeerListenerFactory  
  17.         class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"  
  18.         properties="port=40004,socketTimeoutMillis=120000" />  
  19.   
  20.     <!-- 默认缓存 -->  
  21.     <defaultCache maxElementsInMemory="10000" eternal="false"  
  22.         timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true"  
  23.         diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000"  
  24.         diskPersistent="false" diskExpiryThreadIntervalSeconds="120"  
  25.         memoryStoreEvictionPolicy="LRU">  
  26.     </defaultCache>  
  27.   
  28.     <!-- 缓存 -->  
  29.     <cache name="metaCache"   
  30.         maxElementsInMemory="1000"   
  31.         eternal="false"  
  32.         timeToIdleSeconds="2000"   
  33.         timeToLiveSeconds="1000"   
  34.         overflowToDisk="false">  
  35.         <cacheEventListenerFactory  
  36.             class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />  
  37.         <!-- <bootstrapCacheLoaderFactory  
  38.             class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory"  
  39.             properties="bootstrapAsynchronously=false" /> -->  
  40.     </cache>  
  41. </ehcache>  

到此为止,放入缓存,也就是发送端配置好了,下面开始创建另个Java Project(),User类不变,必须要注意的是序列化UID和上一个Java Project要一致,否则会报ClassNotFound的错误,下面是测试类:

[java]  view plain  copy
  1. package ehcache;  
  2.   
  3. import java.net.URL;  
  4.   
  5. import test.User;  
  6. import junit.framework.TestCase;  
  7. import net.sf.ehcache.Cache;  
  8. import net.sf.ehcache.CacheManager;  
  9. import net.sf.ehcache.Element;  
  10.   
  11. public class TestGetCache extends TestCase {  
  12.       
  13.     public void testGet() throws Exception {  
  14.         URL url = TestGetCache.class.getClassLoader().getResource(  
  15.                 "conf/ehcache.xml");  
  16.         CacheManager manager = new CacheManager(url);  
  17.           
  18.         Cache cache = manager.getCache("metaCache");  
  19.           
  20.         while (true) {  
  21.             System.out.println("搜索中...");  
  22.             System.out.println("当前资源数:" + cache.getSize());  
  23.             Element element = cache.get("key");  
  24.             if (element != null) {  
  25.                 User user = (User)element.getValue();  
  26.                 System.out.println(user.getName());  
  27.                 break;  
  28.             }  
  29.             Thread.sleep(1000);  
  30.         }  
  31.     }  
  32. }  
ehcache.xml配置文件如下:

[html]  view plain  copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2.   
  3. <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.          xsi:noNamespaceSchemaLocation="ehcache.xsd"  
  5.          updateCheck="true" monitoring="autodetect"  
  6.          dynamicConfig="true">  
  7.   
  8.     <diskStore path="java.io.tmpdir" />  
  9.   
  10.     <!-- 指定除自身之外的网络群体中其他提供同步的主机列表,用“|”分开不同的主机 -->  
  11.     <cacheManagerPeerProviderFactory  
  12.         class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"  
  13.         properties="peerDiscovery=manual,rmiUrls=//localhost:40004/metaCache|//localhost:60000/metaCache" />  
  14.   
  15.     <!-- 配宿主主机配置监听程序,来发现其他主机发来的同步请求 -->  
  16.     <cacheManagerPeerListenerFactory  
  17.         class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"  
  18.         properties="port=40004,socketTimeoutMillis=120000" />  
  19.   
  20.     <!-- 默认缓存 -->  
  21.     <defaultCache maxElementsInMemory="10000" eternal="false"  
  22.         timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true"  
  23.         diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000"  
  24.         diskPersistent="false" diskExpiryThreadIntervalSeconds="120"  
  25.         memoryStoreEvictionPolicy="LRU">  
  26.     </defaultCache>  
  27.   
  28.     <!-- 缓存 -->  
  29.     <cache name="metaCache"   
  30.         maxElementsInMemory="1000"   
  31.         eternal="false"  
  32.         timeToIdleSeconds="2000"   
  33.         timeToLiveSeconds="1000"   
  34.         overflowToDisk="false">  
  35.         <cacheEventListenerFactory  
  36.             class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />  
  37. <!--         <bootstrapCacheLoaderFactory  
  38.             class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory"  
  39.             properties="bootstrapAsynchronously=true" /> -->  
  40.     </cache>  
  41. </ehcache>  
下面就可以测试了,首先运行后一个java Project项目,然后运行前一个java Project,运行结果为:1,张三。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值