開發(fā)環(huán)境:
System:Windows
JavaEE Server:tomcat5.0.2.8、tomcat6
JavaSDK: jdk6+
IDE:eclipse、MyEclipse 6.6
開發(fā)依賴庫:
JDK6、 JavaEE5、ehcache-core-2.5.2.jar
Email:hoojo_@126.com
Blog:http://blog.csdn.net/IBM_hoojo
http://hoojo.cnblogs.com/
http://hoojo.blogjava.net
前面2篇文章介紹到Ehcache 整合Spring 使用頁面、對(duì)象緩存 http://www.cnblogs.com/hoojo/archive/2012/07/12/2587556.html
在Spring、Hibernate中使用Ehcache緩存 http://www.cnblogs.com/hoojo/archive/2012/07/12/2587941.html
一、緩存系統(tǒng)簡介
EhCache 是一個(gè)純 Java 的進(jìn)程內(nèi)緩存框架,具有快速、精干等特點(diǎn),是 Hibernate 中默認(rèn)的 CacheProvider。
EhCache 應(yīng)用架構(gòu)圖,下圖是 EhCache 在應(yīng)用程序中的位置:

EhCache 的主要特性有:
1. 快速、精干;
2. 簡單;
3. 多種緩存策略;
4. 緩存數(shù)據(jù)有兩級(jí):內(nèi)存和磁盤,因此無需擔(dān)心容量問題;
5. 緩存數(shù)據(jù)會(huì)在虛擬機(jī)重啟的過程中寫入磁盤;
6. 可以通過 RMI、可插入 API 等方式進(jìn)行分布式緩存;
7. 具有緩存和緩存管理器的偵聽接口;
8. 支持多緩存管理器實(shí)例,以及一個(gè)實(shí)例的多個(gè)緩存區(qū)域;
9. 提供 Hibernate 的緩存實(shí)現(xiàn);
由于 EhCache 是進(jìn)程中的緩存系統(tǒng),一旦將應(yīng)用部署在集群環(huán)境中,每一個(gè)節(jié)點(diǎn)維護(hù)各自的緩存數(shù)據(jù),當(dāng)某個(gè)節(jié)點(diǎn)對(duì)緩存數(shù)據(jù)進(jìn)行更新,這些更新的數(shù)據(jù)無法在其它節(jié)點(diǎn)中共享,這不僅會(huì)降低節(jié)點(diǎn)運(yùn)行的效率,而且會(huì)導(dǎo)致數(shù)據(jù)不同步的情況發(fā)生。例如某個(gè)網(wǎng)站采用 A、B 兩個(gè)節(jié)點(diǎn)作為集群部署,當(dāng) A 節(jié)點(diǎn)的緩存更新后,而 B 節(jié)點(diǎn)緩存尚未更新就可能出現(xiàn)用戶在瀏覽頁面的時(shí)候,一會(huì)是更新后的數(shù)據(jù),一會(huì)是尚未更新的數(shù)據(jù),盡管我們也可以通過 Session Sticky 技術(shù)來將用戶鎖定在某個(gè)節(jié)點(diǎn)上,但對(duì)于一些交互性比較強(qiáng)或者是非 Web 方式的系統(tǒng)來說,Session Sticky 顯然不太適合。
所以就需要用到 EhCache 的集群解決方案。
從1.2版本開始,Ehcache可以使用分布式的緩存了。EhCache 從 1.7 版本開始,支持五種集群方案,分別是:
• Terracotta
• RMI
• JMS
• JGroups
• EhCache Server
其中的三種最為常用集群方式,分別是 RMI、JGroups 以及 EhCache Server 。本文主要介紹RMI的方式。
分布式這個(gè)特性是以plugin的方式實(shí)現(xiàn)的。Ehcache自帶了一些默認(rèn)的分布式緩存插件實(shí)現(xiàn),這些插件可以滿足大部分應(yīng)用的需要。如果需要使用其他的插件那就需要自己開發(fā)了,開發(fā)者可以通過查看distribution包里的源代碼及JavaDoc來實(shí)現(xiàn)它。盡管不是必須的,在使用分布式緩存時(shí)理解一些ehcahce的設(shè)計(jì)思想也是有幫助的。這可以參看分布式緩存設(shè)計(jì)的頁面。以下的部分將展示如何讓分布式插件同ehcache一起工作。
下面列出的是一些分布式緩存中比較重要的方面:
• 你如何知道集群環(huán)境中的其他緩存?
• 分布式傳送的消息是什么形式?
• 什么情況需要進(jìn)行復(fù)制?增加(Puts),更新(Updates)或是失效(Expiries)?
• 采用什么方式進(jìn)行復(fù)制?同步還是異步方式?
為了安裝分布式緩存,你需要配置一個(gè)PeerProvider、一個(gè)CacheManagerPeerListener,
它們對(duì)于一個(gè)CacheManager來說是全局的。每個(gè)進(jìn)行分布式操作的cache都要添加一個(gè)cacheEventListener來傳送消息。
二、集群緩存概念及其配置
正確的元素類型
只有可序列化的元素可以進(jìn)行復(fù)制。一些操作,比如移除,只需要元素的鍵值而不用整個(gè)元素;在這樣的操作中即使元素不是可序列化的但鍵值是可序列化的也可以被復(fù)制。
成員發(fā)現(xiàn)(Peer Discovery)
Ehcache進(jìn)行集群的時(shí)候有一個(gè)cache組的概念。每個(gè)cache都是其他cache的一個(gè)peer,沒有主cache的存在。剛才我們問了一個(gè)問題:你如何知道集群環(huán)境中的其他緩存?這個(gè)問題可以命名為成員發(fā)現(xiàn)(Peer Discovery)。
Ehcache提供了兩種機(jī)制用來進(jìn)行成員發(fā)現(xiàn),就像一輛汽車:手動(dòng)檔和自動(dòng)檔。要使用一個(gè)內(nèi)置的成員發(fā)現(xiàn)機(jī)制要在ehcache的配置文件中指定cacheManagerPeerProviderFactory元素的class屬性為
net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory。
自動(dòng)的成員發(fā)現(xiàn)
自動(dòng)的發(fā)現(xiàn)方式用TCP廣播機(jī)制來確定和維持一個(gè)廣播組。它只需要一個(gè)簡單的配置可以自動(dòng)的在組中添加和移除成員。在集群中也不需要什么優(yōu)化服務(wù)器的知識(shí),這是默認(rèn)推薦的。
成員每秒向群組發(fā)送一個(gè)“心跳”。如果一個(gè)成員 5秒種都沒有發(fā)出信號(hào)它將被群組移除。如果一個(gè)新的成員發(fā)送了一個(gè)“心跳”它將被添加進(jìn)群組。
任何一個(gè)用這個(gè)配置安裝了復(fù)制功能的cache都將被其他的成員發(fā)現(xiàn)并標(biāo)識(shí)為可用狀態(tài)。
要設(shè)置自動(dòng)的成員發(fā)現(xiàn),需要指定ehcache配置文件中cacheManagerPeerProviderFactory元素的properties屬性,就像下面這樣:
peerDiscovery=automatic
multicastGroupAddress=multicast address | multicast host name
multicastGroupPort=port
timeToLive=0-255 (timeToLive屬性詳見常見問題部分的描述)
示例
假設(shè)你在集群中有兩臺(tái)服務(wù)器。你希望同步sampleCache1和sampleCache2。每臺(tái)獨(dú)立的服務(wù)器都要有這樣的配置:
配置server1和server2
<cacheManagerPeerProviderFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
properties="peerDiscovery=automatic, multicastGroupAddress=230.0.0.1,
multicastGroupPort=4446, timeToLive=32"/>
手動(dòng)進(jìn)行成員發(fā)現(xiàn)
進(jìn)行手動(dòng)成員配置要知道每個(gè)監(jiān)聽器的IP地址和端口。成員不能在運(yùn)行時(shí)動(dòng)態(tài)地添加和移除。在技術(shù)上很難使用廣播的情況下就可以手動(dòng)成員發(fā)現(xiàn),例如在集群的服務(wù)器之間有一個(gè)不能傳送廣播報(bào)文的路由器。你也可以用手動(dòng)成員發(fā)現(xiàn)進(jìn)行單向的數(shù)據(jù)復(fù)制,只讓server2知道server1,而server1不知道server2。
配置手動(dòng)成員發(fā)現(xiàn),需要指定ehcache配置文件中cacheManagerPeerProviderFactory的properties屬性,像下面這樣:
peerDiscovery=manual rmiUrls=//server:port/cacheName, //server:port/cacheName ...
rmiUrls配置的是服務(wù)器cache peers的列表。注意不要重復(fù)配置。
示例
假設(shè)你在集群中有兩臺(tái)服務(wù)器。你要同步sampleCache1和sampleCache2。下面是每個(gè)服務(wù)器需要的配置:
配置server1
<cacheManagerPeerProviderFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
properties="peerDiscovery=manual,
rmiUrls=//server2:40001/sampleCache11|//server2:40001/sampleCache12"/>
配置server2
<cacheManagerPeerProviderFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
properties="peerDiscovery=manual,
rmiUrls=//server1:40001/sampleCache11|//server1:40001/sampleCache12"/>
配置CacheManagerPeerListener
每個(gè)CacheManagerPeerListener監(jiān)聽從成員們發(fā)向當(dāng)前CacheManager的消息。配置CacheManagerPeerListener需要指定一個(gè)CacheManagerPeerListenerFactory,它以插件的機(jī)制實(shí)現(xiàn),用來創(chuàng)建CacheManagerPeerListener。
cacheManagerPeerListenerFactory的屬性有:
class – 一個(gè)完整的工廠類名。
properties – 只對(duì)這個(gè)工廠有意義的屬性,使用逗號(hào)分隔。
Ehcache有一個(gè)內(nèi)置的基于RMI的分布系統(tǒng)。它的監(jiān)聽器是RMICacheManagerPeerListener,這個(gè)監(jiān)聽器可以用
RMICacheManagerPeerListenerFactory來配置。
<cacheManagerPeerListenerFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
properties="hostName=localhost, port=40001,
socketTimeoutMillis=2000"/>
有效的屬性是:
hostname (可選) – 運(yùn)行監(jiān)聽器的服務(wù)器名稱。標(biāo)明了做為集群群組的成員的地址,同時(shí)也是你想要控制的從集群中接收消息的接口。
在CacheManager初始化的時(shí)候會(huì)檢查hostname是否可用。
如果hostName不可用,CacheManager將拒絕啟動(dòng)并拋出一個(gè)連接被拒絕的異常。
如果指定,hostname將使用InetAddress.getLocalHost().getHostAddress()來得到。
警告:不要將localhost配置為本地地址127.0.0.1,因?yàn)樗诰W(wǎng)絡(luò)中不可見將會(huì)導(dǎo)致不能從遠(yuǎn)程服務(wù)器接收信息從而不能復(fù)制。在同一臺(tái)機(jī)器上有多個(gè)CacheManager的時(shí)候,你應(yīng)該只用localhost來配置。
port – 監(jiān)聽器監(jiān)聽的端口。
socketTimeoutMillis (可選) – Socket超時(shí)的時(shí)間。默認(rèn)是2000ms。當(dāng)你socket同步緩存請(qǐng)求地址比較遠(yuǎn),不是本地局域網(wǎng)。你可能需要把這個(gè)時(shí)間配置大些,不然很可能延時(shí)導(dǎo)致同步緩存失敗。
配置CacheReplicators
每個(gè)要進(jìn)行同步的cache都需要設(shè)置一個(gè)用來向CacheManagerr的成員復(fù)制消息的緩存事件監(jiān)聽器。這個(gè)工作要通過為每個(gè)cache的配置增加一個(gè)cacheEventListenerFactory元素來完成。
<!-- Sample cache named sampleCache2. -->
<cache name="sampleCache2"
maxElementsInMemory="10"
eternal="false"
timeToIdleSeconds="100"
timeToLiveSeconds="100"
overflowToDisk="false">
<cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicateAsynchronously=true,replicatePuts=true, replicateUpdates=true, replicateUpdatesViaCopy=false, replicateRemovals=true "/>
</cache>
class – 使用net.sf.ehcache.distribution.RMICacheReplicatorFactory
這個(gè)工廠支持以下屬性:
replicatePuts=true | false – 當(dāng)一個(gè)新元素增加到緩存中的時(shí)候是否要復(fù)制到其他的peers. 默認(rèn)是true。
replicateUpdates=true | false – 當(dāng)一個(gè)已經(jīng)在緩存中存在的元素被覆蓋時(shí)是否要進(jìn)行復(fù)制。默認(rèn)是true。
replicateRemovals= true | false – 當(dāng)元素移除的時(shí)候是否進(jìn)行復(fù)制。默認(rèn)是true。
replicateAsynchronously=true | false – 復(fù)制方式是異步的(指定為true時(shí))還是同步的(指定為false時(shí))。默認(rèn)是true。
replicatePutsViaCopy=true | false – 當(dāng)一個(gè)新增元素被拷貝到其他的cache中時(shí)是否進(jìn)行復(fù)制指定為true時(shí)為復(fù)制,默認(rèn)是true。
replicateUpdatesViaCopy=true | false – 當(dāng)一個(gè)元素被拷貝到其他的cache中時(shí)是否進(jìn)行復(fù)制(指定為true時(shí)為復(fù)制),默認(rèn)是true。
你可以使用ehcache的默認(rèn)行為從而減少配置的工作量,默認(rèn)的行為是以異步的方式復(fù)制每件事;你可以像下面的例子一樣減少RMICacheReplicatorFactory的屬性配置:
<!-- Sample cache named sampleCache4. All missing RMICacheReplicatorFactory properties default to true -->
<cache name="sampleCache4"
maxElementsInMemory="10"
eternal="true"
overflowToDisk="false"
memoryStoreEvictionPolicy="LFU">
<cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"/>
</cache>
常見的問題
Windows上的Tomcat
有一個(gè)Tomcat或者是JDK的bug,在tomcat啟動(dòng)時(shí)如果tomcat的安裝路徑中有空格的話,在啟動(dòng)時(shí)RMI監(jiān)聽器會(huì)失敗。參見http://archives.java.sun.com/cgi-bin/wa?A2=ind0205&L=rmi-users&P=797和http://www.ontotext.com/kim/doc/sys-doc/faq-howto-bugs/known-bugs.html。
由于在Windows上安裝Tomcat默認(rèn)是裝在“Program Files”文件夾里的,所以這個(gè)問題經(jīng)常發(fā)生。
廣播阻斷
自動(dòng)的peer discovery與廣播息息相關(guān)。廣播可能被路由阻攔,像Xen和VMWare這種虛擬化的技術(shù)也可以阻攔廣播。如果這些都打開了,你可能還在要將你的網(wǎng)卡的相關(guān)配置打開。一個(gè)簡單的辦法可以告訴廣播是否有效,
那就是使用ehcache remote debugger來看“心跳”是否可用。
廣播傳播的不夠遠(yuǎn)或是傳得太遠(yuǎn)
你可以通過設(shè)置badly misnamed time to live來控制廣播傳播的距離。用廣播IP協(xié)議時(shí),timeToLive的值指的是數(shù)據(jù)包可以傳遞的域或是范圍。約定如下:
0是限制在同一個(gè)服務(wù)器
1是限制在同一個(gè)子網(wǎng)
32是限制在同一個(gè)網(wǎng)站
64是限制在同一個(gè)region
128是限制在同一個(gè)大洲
255是不限制
譯者按:上面這些資料翻譯的不夠準(zhǔn)確,請(qǐng)讀者自行尋找原文理解吧。
在Java實(shí)現(xiàn)中默認(rèn)值是1,也就是在同一個(gè)子網(wǎng)中傳播。改變timeToLive屬性可以限制或是擴(kuò)展傳播的范圍。
三、 RMI方式緩存集群/配置分布式緩存
RMI 是 Java 的一種遠(yuǎn)程方法調(diào)用技術(shù),是一種點(diǎn)對(duì)點(diǎn)的基于 Java 對(duì)象的通訊方式。EhCache 從 1.2 版本開始就支持 RMI 方式的緩存集群。在集群環(huán)境中 EhCache 所有緩存對(duì)象的鍵和值都必須是可序列化的,也就是必須實(shí)現(xiàn) java.io.Serializable 接口,這點(diǎn)在其它集群方式下也是需要遵守的。
下圖是 RMI 集群模式的結(jié)構(gòu)圖:

采用 RMI 集群模式時(shí),集群中的每個(gè)節(jié)點(diǎn)都是對(duì)等關(guān)系,并不存在主節(jié)點(diǎn)或者從節(jié)點(diǎn)的概念,因此節(jié)點(diǎn)間必須有一個(gè)機(jī)制能夠互相認(rèn)識(shí)對(duì)方,必須知道其它節(jié)點(diǎn)的信息,包括主機(jī)地址、端口號(hào)等。EhCache 提供兩種節(jié)點(diǎn)的發(fā)現(xiàn)方式:手工配置和自動(dòng)發(fā)現(xiàn)。手工配置方式要求在每個(gè)節(jié)點(diǎn)中配置其它所有節(jié)點(diǎn)的連接信息,一旦集群中的節(jié)點(diǎn)發(fā)生變化時(shí),需要對(duì)緩存進(jìn)行重新配置。
由于 RMI 是 Java 中內(nèi)置支持的技術(shù),因此使用 RMI 集群模式時(shí),無需引入其它的 Jar 包,EhCache 本身就帶有支持 RMI 集群的功能。使用 RMI 集群模式需要在 ehcache.xml 配置文件中定義 cacheManagerPeerProviderFactory 節(jié)點(diǎn)。
分布式同步緩存要讓這邊的cache知道對(duì)方的cache,叫做Peer Discovery(成員發(fā)現(xiàn)) EHCache實(shí)現(xiàn)成員發(fā)現(xiàn)的方式有兩種:
1、手動(dòng)查找
A、 在ehcache.xml中配置PeerDiscovery成員發(fā)現(xiàn)對(duì)象
Server1配置,配置本地hostName、port是400001,分別監(jiān)聽192.168.8.32:400002的mobileCache和192.168.5.231:400003 的mobileCache。注意這里的mobileCache是緩存的名稱,分別對(duì)應(yīng)著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"/>
<!--
集群多臺(tái)服務(wù)器中的緩存,這里是要同步一些服務(wù)器的緩存
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
注意:每臺(tái)要同步緩存的服務(wù)器的RMI通信socket端口都不一樣,在配置的時(shí)候注意設(shè)置
-->
<!-- server1 的cacheManagerPeerProviderFactory配置 -->
<cacheManagerPeerProviderFactory
class="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元素出現(xiàn)的位置在diskStore下
同樣在你的另外2臺(tái)服務(wù)器上增加配置
Server2,配置本地host,port為400002,分別同步192.168.8.9:400001的mobileCache和192.168.5.231:400003的mobileCache
<!-- server2 的cacheManagerPeerProviderFactory配置 -->
<cacheManagerPeerProviderFactory
class="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配置 -->
<cacheManagerPeerProviderFactory
class="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"
/>
這樣就在三臺(tái)不同的服務(wù)器上配置了手動(dòng)查找cache的PeerProvider成員發(fā)現(xiàn)的配置了。 值得注意的是你在配置rmiUrls的時(shí)候要特別注意url不能重復(fù)出現(xiàn),并且端口、地址都是對(duì)的。
如果指定,hostname將使用InetAddress.getLocalHost().getHostAddress()來得到。
警告:不要將localhost配置為本地地址127.0.0.1,因?yàn)樗诰W(wǎng)絡(luò)中不可見將會(huì)導(dǎo)致不能從遠(yuǎn)程服務(wù)器接收信息從而不能復(fù)制。在同一臺(tái)機(jī)器上有多個(gè)CacheManager的時(shí)候,你應(yīng)該只用localhost來配置。
B、 下面配置緩存和緩存同步監(jiān)聽,需要在每臺(tái)服務(wù)器中的ehcache.xml文件中增加cache配置和cacheEventListenerFactory、cacheLoaderFactory的配置
<defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="30" timeToLiveSeconds="30" overflowToDisk="false"/>
<!--
配置自定義緩存
maxElementsInMemory:緩存中允許創(chuàng)建的最大對(duì)象數(shù)
eternal:緩存中對(duì)象是否為永久的,如果是,超時(shí)設(shè)置將被忽略,對(duì)象從不過期。
timeToIdleSeconds:緩存數(shù)據(jù)空閑的最大時(shí)間,也就是說如果有一個(gè)緩存有多久沒有被訪問就會(huì)被銷毀,如果該值是 0 就意味著元素可以停頓無窮長的時(shí)間。
timeToLiveSeconds:緩存數(shù)據(jù)存活的時(shí)間,緩存對(duì)象最大的的存活時(shí)間,超過這個(gè)時(shí)間就會(huì)被銷毀,這只能在元素不是永久駐留時(shí)有效,如果該值是0就意味著元素可以停頓無窮長的時(shí)間。
overflowToDisk:內(nèi)存不足時(shí),是否啟用磁盤緩存。
memoryStoreEvictionPolicy:緩存滿了之后的淘汰算法。
每一個(gè)小時(shí)更新一次緩存(1小時(shí)過期)
-->
<cache name="mobileCache"
maxElementsInMemory="10000"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="1800"
timeToLiveSeconds="3600"
memoryStoreEvictionPolicy="LFU">
<!--
RMI緩存分布同步查找 class使用net.sf.ehcache.distribution.RMICacheReplicatorFactory
這個(gè)工廠支持以下屬性:
replicatePuts=true | false – 當(dāng)一個(gè)新元素增加到緩存中的時(shí)候是否要復(fù)制到其他的peers。默認(rèn)是true。
replicateUpdates=true | false – 當(dāng)一個(gè)已經(jīng)在緩存中存在的元素被覆蓋時(shí)是否要進(jìn)行復(fù)制。默認(rèn)是true。
replicateRemovals= true | false – 當(dāng)元素移除的時(shí)候是否進(jìn)行復(fù)制。默認(rèn)是true。
replicateAsynchronously=true | false – 復(fù)制方式是異步的指定為true時(shí),還是同步的,指定為false時(shí)。默認(rèn)是true。
replicatePutsViaCopy=true | false – 當(dāng)一個(gè)新增元素被拷貝到其他的cache中時(shí)是否進(jìn)行復(fù)制指定為true時(shí)為復(fù)制,默認(rèn)是true。
replicateUpdatesViaCopy=true | false – 當(dāng)一個(gè)元素被拷貝到其他的cache中時(shí)是否進(jìn)行復(fù)制指定為true時(shí)為復(fù)制,默認(rèn)是true。
asynchronousReplicationIntervalMillis=1000
-->
<!-- 監(jiān)聽RMI同步緩存對(duì)象配置 注冊(cè)相應(yīng)的的緩存監(jiān)聽類,用于處理緩存事件,如put,remove,update,和expire -->
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicateAsynchronously=true,
replicatePuts=true,
replicateUpdates=true,
replicateUpdatesViaCopy=false,
replicateRemovals=true "/>
<!-- 用于在初始化緩存,以及自動(dòng)設(shè)置 -->
<bootstrapCacheLoaderFactory class="net.sf.ehcache.bootstrap.BootstrapCacheLoaderFactory"/>
</cache>
C、 這樣就完成了3臺(tái)服務(wù)器的配置,下面給出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"/>
<!--
集群多臺(tái)服務(wù)器中的緩存,這里是要同步一些服務(wù)器的緩存
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
注意每臺(tái)要同步緩存的服務(wù)器的RMI通信socket端口都不一樣,在配置的時(shí)候注意設(shè)置
-->
<!-- server1 的cacheManagerPeerProviderFactory配置 -->
<cacheManagerPeerProviderFactory
class="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:緩存中允許創(chuàng)建的最大對(duì)象數(shù)
eternal:緩存中對(duì)象是否為永久的,如果是,超時(shí)設(shè)置將被忽略,對(duì)象從不過期。
timeToIdleSeconds:緩存數(shù)據(jù)空閑的最大時(shí)間,也就是說如果有一個(gè)緩存有多久沒有被訪問就會(huì)被銷毀,
如果該值是 0 就意味著元素可以停頓無窮長的時(shí)間。
timeToLiveSeconds:緩存數(shù)據(jù)存活的時(shí)間,緩存對(duì)象最大的的存活時(shí)間,超過這個(gè)時(shí)間就會(huì)被銷毀,
這只能在元素不是永久駐留時(shí)有效,如果該值是0就意味著元素可以停頓無窮長的時(shí)間。
overflowToDisk:內(nèi)存不足時(shí),是否啟用磁盤緩存。
memoryStoreEvictionPolicy:緩存滿了之后的淘汰算法。
每一個(gè)小時(shí)更新一次緩存(1小時(shí)過期)
-->
<cache name="mobileCache"
maxElementsInMemory="10000"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="1800"
timeToLiveSeconds="3600"
memoryStoreEvictionPolicy="LFU">
<!--
RMI緩存分布同步查找 class使用net.sf.ehcache.distribution.RMICacheReplicatorFactory
這個(gè)工廠支持以下屬性:
replicatePuts=true | false – 當(dāng)一個(gè)新元素增加到緩存中的時(shí)候是否要復(fù)制到其他的peers。默認(rèn)是true。
replicateUpdates=true | false – 當(dāng)一個(gè)已經(jīng)在緩存中存在的元素被覆蓋時(shí)是否要進(jìn)行復(fù)制。默認(rèn)是true。
replicateRemovals= true | false – 當(dāng)元素移除的時(shí)候是否進(jìn)行復(fù)制。默認(rèn)是true。
replicateAsynchronously=true | false – 復(fù)制方式是異步的指定為true時(shí),還是同步的,指定為false時(shí)。默認(rèn)是true。
replicatePutsViaCopy=true | false – 當(dāng)一個(gè)新增元素被拷貝到其他的cache中時(shí)是否進(jìn)行復(fù)制指定為true時(shí)為復(fù)制,默認(rèn)是true。
replicateUpdatesViaCopy=true | false – 當(dāng)一個(gè)元素被拷貝到其他的cache中時(shí)是否進(jìn)行復(fù)制指定為true時(shí)為復(fù)制,默認(rèn)是true。
asynchronousReplicationIntervalMillis=1000
-->
<!-- 監(jiān)聽RMI同步緩存對(duì)象配置 注冊(cè)相應(yīng)的的緩存監(jiān)聽類,用于處理緩存事件,如put,remove,update,和expire -->
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicateAsynchronously=true,
replicatePuts=true,
replicateUpdates=true,
replicateUpdatesViaCopy=false,
replicateRemovals=true "/>
<!-- 用于在初始化緩存,以及自動(dòng)設(shè)置 -->
<bootstrapCacheLoaderFactory class="net.sf.ehcache.bootstrap.BootstrapCacheLoaderFactory"/>
</cache>
</ehcache>
2、自動(dòng)發(fā)現(xiàn)
自動(dòng)發(fā)現(xiàn)配置和手動(dòng)查找的方式有一點(diǎn)不同,其他的地方都基本是一樣的。同樣在ehcache.xml中增加配置,配置如下
<!--
搜索某個(gè)網(wǎng)段上的緩存
timeToLive
0是限制在同一個(gè)服務(wù)器
1是限制在同一個(gè)子網(wǎng)
32是限制在同一個(gè)網(wǎng)站
64是限制在同一個(gè)region
128是限制在同一個(gè)大洲
255是不限制
-->
<cacheManagerPeerProviderFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
properties="peerDiscovery=automatic, multicastGroupAddress=192.168.0.1,
multicastGroupPort=400004, timeToLive=32"
/>
其他的配置和手動(dòng)查找方式的配置是一樣的,這里就不再贅述了。關(guān)于ehcache的其他緩存配置方式這里將不再介紹,大家可以自己去研究。可以參考: