RMI方式缓存集群/配置分布式缓存
RMI 是 Java 的一种远程方法调用技术,是一种点对点的基于 Java 对象的通讯方式。EhCache 从 1.2 版本开始就支持 RMI 方式的缓存集群。在集群环境中 EhCache 所有缓存对象的键和值都必须是可序列化的,也就是必须实现 java.io.Serializable 接口,这点在其它集群方式下也是需要遵守的。
下图是 RMI 集群模式的结构图:
采用 RMI 集群模式时,集群中的每个节点都是对等关系,并不存在主节点或者从节点的概念,因此节点间必须有一个机制能够互相认识对方,必须知道其它节点的信息,包括主机地址、端口号等。EhCache 提供两种节点的发现方式:手工配置和自动发现。手工配置方式要求在每个节点中配置其它所有节点的连接信息,一旦集群中的节点发生变化时,需要对缓存进行重新配置。
由于 RMI 是 Java 中内置支持的技术,因此使用 RMI 集群模式时,无需引入其它的 Jar 包,EhCache 本身就带有支持 RMI 集群的功能。使用 RMI 集群模式需要在 ehcache.xml 配置文件中定义 cacheManagerPeerProviderFactory 节点。
分布式同步缓存要让这边的cache知道对方的cache,叫做Peer Discovery(成员发现) EHCache实现成员发现的方式有两种:
1、手动查找
A、 在ehcache.xml中配置PeerDiscovery成员发现对象
Server1配置,配置本地hostName、port是400001,分别监听192.168.8.32:400002的mobileCache和192.168.5.231:400003 的mobileCache。注意这里的mobileCache是缓存的名称,分别对应着server2、server3的cache的配置。
<?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"/><!--
集群多台服务器中的缓存,这里是要同步一些服务器的缓存
server1 hostName:192.168.8.9 port:400001 cacheName:mobileCache
server2 hostName:192.168.8.32 port:400002 cacheName:mobileCache
server3 hostName:192.168.8.231 port:400003 cacheName:mobileCache
注意:每台要同步缓存的服务器的RMI通信socket端口都不一样,在配置的时候注意设置
-->
<!-- server1 的cacheManagerPeerProviderFactory配置 -->
<cacheManagerPeerProviderFactoryclass="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"properties="hostName=localhost,port=400001,socketTimeoutMillis=2000,peerDiscovery=manual,rmiUrls=//192.168.8.32:400002/mobileCache|//192.168.5.231:400003/mobileCache"/>
</ehcache>以上注意cacheManagerPeerProviderFactory元素出现的位置在diskStore下
同样在你的另外2台服务器上增加配置
Server2,配置本地host,port为400002,分别同步192.168.8.9:400001的mobileCache和192.168.5.231:400003的mobileCache
<!-- server2 的cacheManagerPeerProviderFactory配置 -->
<cacheManagerPeerProviderFactoryclass="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"properties="hostName=localhost,port=400002,socketTimeoutMillis=2000,peerDiscovery=manual,rmiUrls=//192.168.8.9:400001/mobileCache|//192.168.5.231:400003/mobileCache"/>
Server3,配置本地host,port为400003,分别同步192.168.8.9:400001的mobileCache缓存和192.168.8.32:400002的mobileCache缓存
<!-- server3 的cacheManagerPeerProviderFactory配置 -->
<cacheManagerPeerProviderFactoryclass="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"properties="hostName=localhost,port=400003,socketTimeoutMillis=2000,peerDiscovery=manual,rmiUrls=//192.168.8.9:400001/mobileCache|//192.168.8.32:400002/mobileCache"/>
这样就在三台不同的服务器上配置了手动查找cache的PeerProvider成员发现的配置了。 值得注意的是你在配置rmiUrls的时候要特别注意url不能重复出现,并且端口、地址都是对的。
如果指定,hostname将使用InetAddress.getLocalHost().getHostAddress()来得到。
警告:不要将localhost配置为本地地址127.0.0.1,因为它在网络中不可见将会导致不能从远程服务器接收信息从而不能复制。在同一台机器上有多个CacheManager的时候,你应该只用localhost来配置。
B、 下面配置缓存和缓存同步监听,需要在每台服务器中的ehcache.xml文件中增加cache配置和cacheEventListenerFactory、cacheLoaderFactory的配置
<defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="30" timeToLiveSeconds="30" overflowToDisk="false"/><!--
配置自定义缓存
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 -->
<cacheEventListenerFactoryclass="net.sf.ehcache.distribution.RMICacheReplicatorFactory"properties="replicateAsynchronously=true,replicatePuts=true,replicateUpdates=true,replicateUpdatesViaCopy=false,replicateRemovals=true "/>
<!-- 用于在初始化缓存,以及自动设置 -->
<bootstrapCacheLoaderFactory class="net.sf.ehcache.bootstrap.BootstrapCacheLoaderFactory"/></cache>
C、 这样就完成了3台服务器的配置,下面给出server1的完整的ehcache.xml的配置
<?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"/><!--
集群多台服务器中的缓存,这里是要同步一些服务器的缓存
server1 hostName:192.168.8.9 port:400001 cacheName:mobileCache
server2 hostName:192.168.8.32 port:400002 cacheName:mobileCache
server3 hostName:192.168.8.231 port:400003 cacheName:mobileCache
注意每台要同步缓存的服务器的RMI通信socket端口都不一样,在配置的时候注意设置
-->
<!-- server1 的cacheManagerPeerProviderFactory配置 -->
<cacheManagerPeerProviderFactoryclass="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"properties="hostName=localhost,port=400001,socketTimeoutMillis=2000,peerDiscovery=manual,rmiUrls=//192.168.8.32:400002/mobileCache|//192.168.5.231:400003/mobileCache"/>
<defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="30" timeToLiveSeconds="30" overflowToDisk="false"/><!--
配置自定义缓存
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 -->
<cacheEventListenerFactoryclass="net.sf.ehcache.distribution.RMICacheReplicatorFactory"properties="replicateAsynchronously=true,replicatePuts=true,replicateUpdates=true,replicateUpdatesViaCopy=false,replicateRemovals=true "/>
<!-- 用于在初始化缓存,以及自动设置 -->
<bootstrapCacheLoaderFactory class="net.sf.ehcache.bootstrap.BootstrapCacheLoaderFactory"/></cache></ehcache>
2、自动发现
自动发现配置和手动查找的方式有一点不同,其他的地方都基本是一样的。同样在ehcache.xml中增加配置,配置如下
<!--
搜索某个网段上的缓存
timeToLive
0是限制在同一个服务器
1是限制在同一个子网
32是限制在同一个网站
64是限制在同一个region
128是限制在同一个大洲
255是不限制
-->
<cacheManagerPeerProviderFactoryclass="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"properties="peerDiscovery=automatic, multicastGroupAddress=192.168.0.1,multicastGroupPort=400004, timeToLive=32"/>
其他的配置和手动查找方式的配置是一样的,这里就不再赘述了。关于ehcache的其他缓存配置方式这里将不再介绍,大家可以自己去研究。可以参考: