ehcache 实现缓存共享

来源:互联网 发布:中国铁矿石进口数据 编辑:程序博客网 时间:2024/05/16 17:53

公司项目最近在做缓存同步的工作,研发组搞了一套zookeeper的插件,缓存存放在ehcache中,因为要依赖第三方插件,感觉很麻烦,ehcache本身就支持缓存同步且方式比较多。

如下样例简单实现两个应用之间的ehcache缓存共享(RMI),同步更新。

同步运行两个Java程序发现跟新缓存会同步更新,具体代码不做解释,工程师们运行一把就知真相。


节点一

ehcache.xml

 
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true"
  monitoring="autodetect" dynamicConfig="true">


<diskStore path="e:\\Data" />  
<defaultCache 
maxElementsInMemory="1000" 
eternal="true" 
timeToIdleSeconds="3600" 
timeToLiveSeconds="3600" 
overflowToDisk="true" 
/>
<cache name="a" 
maxElementsInMemory="1000" 
eternal="true" 
timeToIdleSeconds="3600" 
timeToLiveSeconds="3600" 
overflowToDisk="true"
diskPersistent="true"
/>
<cacheManagerPeerProviderFactory
            class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
            properties="peerDiscovery=manual,
  rmiUrls=//localhost:40002/sampleDistributedCache2"
            propertySeparator=","
    />
<cacheManagerPeerListenerFactory
            class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
            properties="hostName=localhost, port=40001, socketTimeoutMillis=2000" 
    />
   <cache name="sampleDistributedCache2"
           maxElementsInMemory="1000000"
           eternal="false"
           timeToIdleSeconds="100"
           timeToLiveSeconds="100"
           overflowToDisk="false">
        <cacheEventListenerFactory
                class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
                properties="replicateAsynchronously=true, replicatePuts=true,
                            replicatePutsViaCopy=true, replicateUpdates=true,
                            replicateUpdatesViaCopy=true, replicateRemovals=true,
                            asynchronousReplicationIntervalMillis=200"/>
        <bootstrapCacheLoaderFactory
                class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory"/>
    </cache>    
</ehcache>

节点二配置文件 ehcache2.xml

 
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true"
  monitoring="autodetect" dynamicConfig="true">


<diskStore path="e:\\Data" />  
<defaultCache 
maxElementsInMemory="1000" 
eternal="true" 
timeToIdleSeconds="3600" 
timeToLiveSeconds="3600" 
overflowToDisk="true" 
/>
<cache name="a" 
maxElementsInMemory="1000" 
eternal="true" 
timeToIdleSeconds="3600" 
timeToLiveSeconds="3600" 
overflowToDisk="true"
diskPersistent="true"
/>
    
    <cacheManagerPeerProviderFactory
            class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
            properties="peerDiscovery=manual,
  rmiUrls=//localhost:40001/sampleDistributedCache2"
            propertySeparator=","
    />
<cacheManagerPeerListenerFactory
            class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
            properties="hostName=localhost, port=40002, socketTimeoutMillis=2000" 
    />
   <cache name="sampleDistributedCache2"
           maxElementsInMemory="10000"
           eternal="false"
           timeToIdleSeconds="100"
           timeToLiveSeconds="100"
           overflowToDisk="false">
        <cacheEventListenerFactory
                class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
                properties="replicateAsynchronously=true, replicatePuts=true,
                            replicatePutsViaCopy=true, replicateUpdates=true,
                            replicateUpdatesViaCopy=true, replicateRemovals=true,
                            asynchronousReplicationIntervalMillis=200"/>
        <bootstrapCacheLoaderFactory
                class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory"/>
    </cache>
    </ehcache>
    
    代码部分

节点一代码:

package my.test.ehcache;
import java.lang.management.ManagementFactory;
import javax.management.MBeanServer;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import net.sf.ehcache.management.ManagementService;
public class EHCacheTest {
public static void main(String[] args) {
CacheManager cacheManager = CacheManager.create("src/com/x/ehcache.xml");
//读入配置
//打印初始缓存
String[] cacheNames = cacheManager.getCacheNames();
printNames(cacheNames);
//移除缓存
cacheManager.removeCache("sampleDistributedCache1");
cacheNames = cacheManager.getCacheNames();
printNames(cacheNames);
// distributed -- rmi同步
Cache cache = cacheManager.getCache("sampleDistributedCache2");
//注册被管理的Bean
// JMX -- jconsole(MBeanServer)
MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
ManagementService.registerMBeans(cacheManager, mBeanServer, true, true,
true, true); 
for (int i = 0; i < 100000; i++) {
Element temp = cache.get("ehcache");
System.out.println("cache.getSize()="+cache.getSize());
cache.put(new Element(i, i));
System.out.println("第"+i+"次cache.put");
if (temp != null) {
System.out.println(temp.getValue());
} else {
System.out.println("NotFound");
}
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private static void printNames(String[] names) {
System.out.println("=======================");
for (int i = 0; i < names.length; i++) {
System.out.println(names[i]);
}
}
}

节点二代码:


package my.test.ehcache2;


import java.io.InputStream;
import java.lang.management.ManagementFactory;
import javax.management.MBeanServer;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import net.sf.ehcache.Statistics;
import net.sf.ehcache.management.ManagementService;
public class EHCacheTest {
public static void main(String[] args) {
 
//读入配置
CacheManager cacheManager = CacheManager.create("src/com/x/ehcache2.xml");
//打印初始缓存
String[] cacheNames = cacheManager.getCacheNames();
//注册管理Bean
MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
ManagementService.registerMBeans(cacheManager, mBeanServer, true, true, true, true);
//distributed
Cache cache = cacheManager.getCache("sampleDistributedCache2");
//添加值后另一个虚拟机的缓存通过RMI会同步缓存,并读到这个值
cache.put(new Element("ehcache", "newaddvalue"));
printCache(cache);
for (int i = 0; i < 10000; i++) {
try {
Thread.sleep(3000);
System.out.println("第"+i+"次加载cache.size="+cache.getSize());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
        }
}
private static void printCache(Cache cache) {
int size = cache.getSize();
long memSize = cache.getMemoryStoreSize();
long diskSize = cache.getDiskStoreSize();
Statistics stat = cache.getStatistics();
long hits = stat.getCacheHits();
StringBuilder sb = new StringBuilder();
sb.append("size=" + size + ";memsize=" + memSize);
sb.append(";diskSize=" + diskSize + ";hits=" + hits);
System.out.println(sb.toString());
}
}

1 0