EhCache RMI方式分布式缓存解决方案

在网上看到很多Ehcache RMI分布式缓存的配置,自己动手亲自试验了一下,也走了不少弯路,在此总结一下。

在此感谢博文http://www.cnblogs.com/daxin/p/3568687.html,给了我很大帮助,而且博客页面很漂亮,很容易读。

我主要使用“手动成员发现”配置的。我的测试环境是在同一机子启两个ehcache。

1. 在netbeans中,新建两个java项目,分别命名EhcacheDemo和EhcacheDemo2。

2. 编写ehcache.xml,存放在源包下

EhcacheDemo项目中配置如下:

<?xml version="1.0" encoding="gbk"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd">
    <diskStore path="java.io.tmpdir/test2"/>
    <!-- 集群多台服务器中的缓存,这里是要同步一些服务器的缓存
        server1 hostName:192.168.8.9 port:40001 cacheName:mobileCache
        server2 hostName:192.168.8.32 port:40002 cacheName:mobileCache
        注意:每台要同步缓存的服务器的RMI通信socket端口都不一样,在配置的时候注意设置
    -->    
    <!-- server1 的cacheManagerPeerProviderFactory配置 -->
    <cacheManagerPeerProviderFactory 
        class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory" 
        properties="hostName=localhost,
        port=40001,
        socketTimeoutMillis=2000,
        peerDiscovery=manual,
        rmiUrls=//localhost:40002/mobileCache"/>
    <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="30" timeToLiveSeconds="30" overflowToDisk="false"/>
    
    <cacheManagerPeerListenerFactory
        class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
        properties="hostName=localhost, port=40001,
        socketTimeoutMillis=2000"/>
    
    <!-- 
    配置自定义缓存
    maxElementsInMemory:缓存中允许创建的最大对象数
    eternal:缓存中对象是否为永久的,如果是,超时设置将被忽略,对象从不过期。
    timeToIdleSeconds:缓存数据空闲的最大时间,也就是说如果有一个缓存有多久没有被访问就会被销毁,如果该值是 0 就意味着元素可以停顿无穷长的时间。
    timeToLiveSeconds:缓存数据存活的时间,缓存对象最大的的存活时间,超过这个时间就会被销毁,这只能在元素不是永久驻留时有效,如果该值是0就意味着元素可以停顿无穷长的时间。
    overflowToDisk:内存不足时,是否启用磁盘缓存。
    memoryStoreEvictionPolicy:缓存满了之后的淘汰算法。    
    每一个小时更新一次缓存(1小时过期) 
    -->
    <cache name="mobileCache"
           maxElementsInMemory="10000"
           eternal="false"
           overflowToDisk="true"
           timeToIdleSeconds="1800"
           timeToLiveSeconds="3600"
           memoryStoreEvictionPolicy="LFU">
        <!-- 
        RMI缓存分布同步查找 class使用net.sf.ehcache.distribution.RMICacheReplicatorFactory
        这个工厂支持以下属性:
        replicatePuts=true | false – 当一个新元素增加到缓存中的时候是否要复制到其他的peers。默认是true。
        replicateUpdates=true | false – 当一个已经在缓存中存在的元素被覆盖时是否要进行复制。默认是true。
        replicateRemovals= true | false – 当元素移除的时候是否进行复制。默认是true。
        replicateAsynchronously=true | false – 复制方式是异步的(指定为true时)还是同步的(指定为false时)。默认是true。
        replicatePutsViaCopy=true | false – 当一个新增元素被拷贝到其他的cache中时是否进行复制(指定为true时为复制),默认是true。
        replicateUpdatesViaCopy=true | false – 当一个元素被拷贝到其他的cache中时是否进行复制(指定为true时为复制),默认是true。
        asynchronousReplicationIntervalMillis=1000
        -->
        <!-- 监听RMI同步缓存对象配置 注册相应的的缓存监听类,用于处理缓存事件,如put,remove,update,和expire -->
        <cacheEventListenerFactory
            class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
            properties="replicateAsynchronously=false"/>
        <!-- 用于在初始化缓存,以及自动设置 -->        
        <bootstrapCacheLoaderFactory  class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory"/>  

    </cache>
</ehcache>

EhcacheDemo2项目中配置如下:

<?xml version="1.0" encoding="gbk"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd">
    <diskStore path="java.io.tmpdir/test1"/>
    <!-- 
        集群多台服务器中的缓存,这里是要同步一些服务器的缓存
        server1 hostName:192.168.8.9 port:400001 cacheName:mobileCache
        server2 hostName:192.168.8.32 port:400002 cacheName:mobileCache
        注意:每台要同步缓存的服务器的RMI通信socket端口都不一样,在配置的时候注意设置
    -->    
    <!-- server1 的cacheManagerPeerProviderFactory配置 -->
    <cacheManagerPeerProviderFactory 
        class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory" 
        properties="hostName=localhost,
        port=40002,
        socketTimeoutMillis=2000,
        peerDiscovery=manual,
        rmiUrls=//localhost:40001/mobileCache"/>
    <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="30" timeToLiveSeconds="30" overflowToDisk="false"/>
    
    <cacheManagerPeerListenerFactory
        class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
        properties="hostName=localhost, port=40002,
        socketTimeoutMillis=2000"/>
    
    <!-- 
    配置自定义缓存
    maxElementsInMemory:缓存中允许创建的最大对象数
    eternal:缓存中对象是否为永久的,如果是,超时设置将被忽略,对象从不过期。
    timeToIdleSeconds:缓存数据空闲的最大时间,也就是说如果有一个缓存有多久没有被访问就会被销毁,如果该值是 0 就意味着元素可以停顿无穷长的时间。
    timeToLiveSeconds:缓存数据存活的时间,缓存对象最大的的存活时间,超过这个时间就会被销毁,这只能在元素不是永久驻留时有效,如果该值是0就意味着元素可以停顿无穷长的时间。
    overflowToDisk:内存不足时,是否启用磁盘缓存。
    memoryStoreEvictionPolicy:缓存满了之后的淘汰算法。    
    每一个小时更新一次缓存(1小时过期) 
    -->
    <cache name="mobileCache"
           maxElementsInMemory="10000"
           eternal="false"
           overflowToDisk="true"
           timeToIdleSeconds="1800"
           timeToLiveSeconds="3600"
           memoryStoreEvictionPolicy="LFU">   
        <!-- 
        RMI缓存分布同步查找 class使用net.sf.ehcache.distribution.RMICacheReplicatorFactory
        这个工厂支持以下属性:
        replicatePuts=true | false – 当一个新元素增加到缓存中的时候是否要复制到其他的peers。默认是true。
        replicateUpdates=true | false – 当一个已经在缓存中存在的元素被覆盖时是否要进行复制。默认是true。
        replicateRemovals= true | false – 当元素移除的时候是否进行复制。默认是true。
        replicateAsynchronously=true | false – 复制方式是异步的指定为true时,还是同步的,指定为false时。默认是true。
        replicatePutsViaCopy=true | false – 当一个新增元素被拷贝到其他的cache中时是否进行复制指定为true时为复制,默认是true。
        replicateUpdatesViaCopy=true | false – 当一个元素被拷贝到其他的cache中时是否进行复制指定为true时为复制,默认是true。
        asynchronousReplicationIntervalMillis=1000
        -->
        <!-- 监听RMI同步缓存对象配置 注册相应的的缓存监听类,用于处理缓存事件,如put,remove,update,和expire -->
        <cacheEventListenerFactory
            class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
            properties="replicateAsynchronously=false"/>
        <!-- 用于在初始化缓存,以及自动设置 -->
        <bootstrapCacheLoaderFactory  class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory"/>  
    </cache>
</ehcache>

3. 引用jar包

(1)ehcache-2.8.3.jar

(2)slf4j-api-1.6.6.jar

(3)slf4j-jdk14-1.6.6.jar

4. 编写测试类

EhcacheDemo项目UsingCacheCluster.java:

import java.net.URL;
import java.util.List;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;

public class UsingCacheCluster {

    public static void main(String[] args) throws Exception {
        UsingCacheCluster uc = new UsingCacheCluster();

        URL url = uc.getClass().getResource("ehcache1.xml");
        if (url == null) {
            System.out.println("null");
            return;
        } else {
            System.out.println(url);
//            return;
        }

        CacheManager manager = new CacheManager(url);
        Cache cache = manager.getCache("mobileCache");
        int i = 0;
        int k = 100;
        while (true) {
            Thread.sleep(4500);
            cache.put(new Element("read:" + k, "read:" + k++));
            List<String> list = cache.getKeys();
            System.out.println(i++);
            for (String str : list) {
                System.out.print(str + "\t");
            }
            System.out.println("");
        }
    }
}

EhcacheDemo2项目UsingCacheCluster.java:

import java.net.URL;
import java.util.List;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;

public class UsingCacheCluster {

    public static void main(String[] args) throws Exception {
        UsingCacheCluster uc = new UsingCacheCluster();

        URL url = uc.getClass().getResource("../../ehcache1.xml");
        if (url == null) {
            System.out.println("null");
            return;
        }else{
            System.out.println(url);
//            return;
        }
        CacheManager manager = new CacheManager(url);
        Cache cache = manager.getCache("mobileCache");
        int i = 0;
        while (true) {
            Thread.sleep(4500);
            List<String> list = cache.getKeys();
            System.out.println(i++);
            for (Object str : list) {
                System.out.print("aa" + str + "\t");
            }
            System.out.println();
        }
    }
    
}

5. 运行java程序,即可见到效果哦,嘿嘿,很简单的。

ehcache的jar包到官网即可下载。

我当初是使用java web项目进行测试的,结果测试类写错了,误以为是配置ehcache出错,找了许久,也没有找到原因,后来改用java项目来测试,发现我的ehcache的配置没有问题。在这提醒大家一下,如果使用java web项目来测试的话,CacheManager生命周期同tomcat一样长(若使用了tomcat来测试,其它的服务器也一样),不关闭tomcat,就不要关闭CacheManager,不然,看不到复制的效果,嘿嘿,祝大家好运吧,原本想传demo源码上来的,但是想想,我写的已经很清楚了,如果哪位不明白的话,可以@我哦,嘿嘿,今天先这样了。




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值