1. 程式人生 > >ehcache 實現快取共享

ehcache 實現快取共享

公司專案最近在做快取同步的工作,研發組搞了一套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());
}
}