Ehcache缓存
概述
Ehcache的类层次模型主要为三层,最上层的是CacheManager,它是操作Ehcache的入口。我们可以通过CacheManager.getInstance()获得一个单CacheManager,或者通过CacheManager的构造函数创建一个新的CacheManager。每个CacheManager都管理着多个Cache。而每个Cache都以一种hash的方式关联着多个Element。而Element则是我们用于存放缓存内容的地方。
配置文件(ehcache.xml放置于项目根目录下)
例子:
ehcache.xml
<?xml version="1.0" encoding="UTF-8" ?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation=" ehcache.xsd" updateCheck="true" monitoring="autodetect" dynamicConfig="true"> <defaultCache maxElementsInMemory="2" eternal="false" timeToIdleSeconds="1" timeToLiveSeconds="1" overflowToDisk="false" memoryStoreEvictionPolicy="LRU"/> <cache name="sampleCache1" maxElementsInMemory="5" eternal="false" overflowToDisk="false" timeToIdleSeconds="1" timeToLiveSeconds="1" memoryStoreEvictionPolicy="LRU"/> </ehcache>
注:在ehcache的配置文件里面必须配置defaultCache。每个<cache>标签定义一个新的cache,属性的含义基本上可以从名字上得到。
实例程序:
package ehcache.test01;
import java.util.List;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Cache;
import net.sf.ehcache.Element;
public class test01 {
/**
* @param args
*/
public static void main(String[] args) throws Exception{
// TODO Auto-generated method stub
//使用ehcache.xml配置文件创建一个缓存管理器
CacheManager manager = new CacheManager("ehcache.xml");
//获得ehcache.xml配置文件中sampleCache1缓存的句柄
Cache cache = manager.getCache("sampleCache1");
for(int i = 0; i< 10 ; i++){
Element e = new Element("key"+ i ,"value" + i );
System.out.println(e.toString());
cache.put(e);
}
//更新一条记录
cache.put(new Element("key7","NewValue7"));
//根据key取得对应element的序列化value值
System.out.println("Get Serializable value : " + cache.get("key7").getValue().toString());
//根据key取得对应element的非序列化value值
System.out.println("Get Non Serializable value : " + cache.get("key7").getObjectValue().toString());
//SampleCache1的配置是支持磁盘持久化的。如果想要保证element即时的被输出到磁盘,可以调用cache.flush();
//cache.flush();
//获得当前cache中的element数量
System.out.println("cache size = " + cache.getSize());
//获得当前MemoryStore中的element数量
System.out.println("cache memorystore size = " + cache.getMemoryStoreSize());
//获得当前DiskStore中element数量
System.out.println("cache Diskstore size = " + cache.getDiskStoreSize());
List<String> keys = cache.getKeys();
//System.out.println(cache.getKeys().size());
for(String key : keys){
System.out.println(key + "," + cache.get(key));
}
}
}
环境为两台机器
主机A ip:192.168.255.131
主机B ip:192.168.255.130
1. RMI方式:
rmi的方式配置要点(下面均是server1上的配置,server2上的只需要把ip兑换即可)
具体说明:配置cacheManagerPeerListenerFactory是配宿主主机配置监听程序,来发现其他主机发来的同步请求
配置cacheManagerPeerProviderFactory是指定除自身之外的网络群体中其他提供同步的主机列表,用“|”分开不同的主机。
下面的例子的测试过程是:主机B缓存开启,并从名为UserCache的缓存中循环抓取键值为“key1”的元素,直到取到,才退出循环。主机A缓存启动,并在名为UserCache的缓存中放入键值为“key1”的元素。显然,如果主机B取到的元素,那么就证明同步成功,也就是集群成功。
所以在测试过程中先启动主机B的测试程序,在启动主机A的测试程序。
注意:确保你所监听的端口已被服务器打开
下面具体说配置文件以及测试程序:
<!--[if !supportLists]-->1. 1、主机A的配置文件以及测试源代码
recluster_ehcache.xml
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd"> <cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory" properties="peerDiscovery=manual,rmiUrls=//192.168.255.130:40000/UserCache"/> <cacheManagerPeerListenerFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory" properties="hostName=192.168.255.131,port=40000,socketTimeoutMillis=120000" /> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"> <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" /> </defaultCache> <cache name="UserCache" maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="100000" timeToLiveSeconds="100000" overflowToDisk="false"> <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" /> </cache> </ehcache>
Java代码
package ehcache;
import java.net.URL;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
public class clustertest {
/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException{
// TODO Auto-generated method stub
//URL url = clustertest.class.getClassLoader().getResource("recluster_ehcache.xml");
CacheManager manager = new CacheManager("recluster_ehcache.xml");
//get Cache
Cache cache = manager.getCache("UserCache");
Element element = new Element("key1", "value1");
cache.put(element);
System.out.println("Initial:\n"//+url.toString()
+"\n"+manager.getName()
+"\n"+cache.getName()
+" 's size = "+cache.getSize()
+"\n"+element.toString());
Element element1 = cache.get("key1");
System.out.println(element1.getValue());
//while(true){
// Thread.sleep(1000);
//}
}
}
2、 主机B上的配置文件以及测试代码
recluster_ehcache.xml
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd"> <cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory" properties="peerDiscovery=manual,rmiUrls=//192.168.255.131:40000/UserCache" /> <cacheManagerPeerListenerFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory" properties="hostName=192.168.255.130,port=40000,socketTimeoutMillis=120000" /> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"> <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" /> </defaultCache> <cache name="UserCache" maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="100000" timeToLiveSeconds="100000" overflowToDisk="false"> <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" /> </cache> </ehcache>
Java代码
package ehcache;
import java.net.URL;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Cache;
import net.sf.ehcache.Element;
public class cluster_B {
/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
//System.out.println("Test begin");
//URL url = cluster_B.class.getClassLoader().getResource("recluster_ehcache.xml");
CacheManager manager = new CacheManager("recluster_ehcache.xml");
//System.out.println(url.toString());
//get Cache
Cache cache = manager.getCache("UserCache");
int i=0;
while(true) {
i++;
System.out.println(i+". "+cache.getName()+" 's size = "+cache.getSize());
Element e = cache.get("key1");
if(e != null) {
System.out.println(e.getValue());
break;
}
Thread.sleep(1000);
}
}
}
主机B上成功取出value1即表示成功
2. JGroups方式:
ehcache 1.5.0之后版本支持的一种方式,配置起来比较简单,要点:
a. 配置PeerProvider,使用tcp的方式,例子如下:
<cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.jgroups.JGroupsCacheManagerPeerProviderFactory" properties="connect=TCP(start_port=7800): TCPPING(initial_hosts=192.168.2.154[7800],192.168.2.23[7800];port_range=10;timeout=3000; num_initial_members=3;up_thread=true;down_thread=true): VERIFY_SUSPECT(timeout=1500;down_thread=false;up_thread=false): pbcast.NAKACK(down_thread=true;up_thread=true;gc_lag=100;retransmit_timeout=3000): pbcast.GMS(join_timeout=5000;join_retry_timeout=2000;shun=false; print_local_addr=false;down_thread=true;up_thread=true)" propertySeparator="::" />
b.为每个cache添加cacheEventListener:
<cache name="userCache" maxElementsInMemory="10000" eternal="true" overflowToDisk="true" timeToIdleSeconds="0" timeToLiveSeconds="0" diskPersistent="false" diskExpiryThreadIntervalSeconds="120"> <cacheEventListenerFactory class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory" properties="replicateAsynchronously=true, replicatePuts=true, replicateUpdates=true, replicateUpdatesViaCopy=false, replicateRemovals=true"/> </cache>
JGroup方式配置的两个server上的配置文件一样,若有多个server,在initial_hosts中将server ip加上即可。
一个完整的ehcache.xml文件:
<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.sf.net/ehcache.xsd"> <diskStore path="java.io.tmpdir" /> <cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.jgroups.JGroupsCacheManagerPeerProviderFactory" properties="connect=TCP(start_port=7800): TCPPING(initial_hosts=192.168.2.154[7800],192.168.2.23[7800];port_range=10;timeout=3000; num_initial_members=3;up_thread=true;down_thread=true): VERIFY_SUSPECT(timeout=1500;down_thread=false;up_thread=false): pbcast.NAKACK(down_thread=true;up_thread=true;gc_lag=100;retransmit_timeout=3000): pbcast.GMS(join_timeout=5000;join_retry_timeout=2000;shun=false; print_local_addr=false;down_thread=true;up_thread=true)" propertySeparator="::" /> <defaultCache maxElementsInMemory="10000" eternal="true" overflowToDisk="true" timeToIdleSeconds="0" timeToLiveSeconds="0" diskPersistent="false" diskExpiryThreadIntervalSeconds="120"> <cacheEventListenerFactory class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory" properties="replicateAsynchronously=true, replicatePuts=true, replicateUpdates=true, replicateUpdatesViaCopy=false, replicateRemovals=true"/> </defaultCache> <cache name="velcroCache" maxElementsInMemory="10000" eternal="true" overflowToDisk="true" timeToIdleSeconds="0" timeToLiveSeconds="0" diskPersistent="false" diskExpiryThreadIntervalSeconds="120"> <cacheEventListenerFactory class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory" properties="replicateAsynchronously=true, replicatePuts=true, replicateUpdates=true, replicateUpdatesViaCopy=false, replicateRemovals=true"/> </cache> <cache name="userCache" maxElementsInMemory="10000" eternal="true" overflowToDisk="true" timeToIdleSeconds="0" timeToLiveSeconds="0" diskPersistent="false" diskExpiryThreadIntervalSeconds="120"> <cacheEventListenerFactory class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory" properties="replicateAsynchronously=true, replicatePuts=true, replicateUpdates=true, replicateUpdatesViaCopy=false, replicateRemovals=true"/> </cache> <cache name="resourceCache" maxElementsInMemory="10000" eternal="true" overflowToDisk="true" timeToIdleSeconds="0" timeToLiveSeconds="0" diskPersistent="false" diskExpiryThreadIntervalSeconds="120"> <cacheEventListenerFactory class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory" properties="replicateAsynchronously=true, replicatePuts=true, replicateUpdates=true, replicateUpdatesViaCopy=false, replicateRemovals=true"/> </cache> </ehcache>