Ehcache 一台服务器多个Tomcat组成的集群间的缓存同步实践

阅读:452 2019-03-19 14:42:06 来源:开源中国

tomcat集群部署情况说明

两台web服务器,每台服务器部署两个tomcat

server1192.168.178.101

tomcat1tomcat2

server2192.168.178.102

tomcat3tomcat4

采用ehcache的rmi方式来实现缓存同步复制

方式一:自动发现集群成员

ehcache.xml配置如下:

xsi:nonamespaceschemalocation="ehcache.xsd"

updatecheck="true"monitoring="autodetect"

dynamicconfig="true">

class="net.sf.ehcache.distribution.rmicachemanagerpeerproviderfactory"

properties="peerdiscovery=automatic,

multicastgroupaddress=230.0.0.1,

multicastgroupport=4446

timetolive=1"/>

class="net.sf.ehcache.distribution.rmicachemanagerpeerlistenerfactory"/>

maxelementsinmemory="100"

eternal="true"

overflowtodisk="false"

memorystoreevictionpolicy="lfu">

ps:

a、配置简单,每个tomcat使用完全相同的ehcache配置;

b、通过多播(multicast)来维护集群中的所有有效节点。这也是最为简单而且灵活的方式,与手工模式不同的是,每个节点上的配置信息都相同,大大方便了节点的部署,避免人为的错漏出现。

c、timetolive的值指的是数据包可以传递的域或是范围。约定如下:

0是限制在同一个服务器

1是限制在同一个子网

32是限制在同一个网站

64是限制在同一个region

128是限制在同一个大洲

255是不限制

在java实现中默认值是1,也就是在同一个子网中传播。改变timetolive属性可以限制或是扩展传播的范围。

d、自动的peerdiscovery与广播息息相关。广播可能被路由阻拦,像xen和vmware这种虚拟化的技术也可以阻拦广播(阿里云主机好像也不提供广播,阿里云服务器上部署时可采用手动配置成员发现)。

如果这些都打开了,你可能还在要将你的网卡的相关配置打开。一个简单的办法可以告诉广播是否有效,那就是使用ehcacheremotedebugger来看“心跳”是否可用。

方式二:手动配置发现集群成员

ehcache.xml配置如下:

xsi:nonamespaceschemalocation="ehcache.xsd"

updatecheck="true"monitoring="autodetect"

dynamicconfig="true">

class="net.sf.ehcache.distribution.rmicachemanagerpeerproviderfactory"

properties="peerdiscovery=manual,

rmiurls=

//192.168.178.101:50001/cache1|

//192.168.178.101:50001/cache2|

//192.168.178.102:40001/cache1|

//192.168.178.102:40001/cache2|

//192.168.178.102:50001/cache1|

//192.168.178.102:50001/cache2"/>

class="net.sf.ehcache.distribution.rmicachemanagerpeerlistenerfactory"

properties="hostname=192.168.178.101,port=40001,sockettimeoutmillis=2000"/>

maxelementsinmemory="1000"

eternal="true"

overflowtodisk="false"

memorystoreevictionpolicy="lfu">

class="net.sf.ehcache.distribution.rmicachereplicatorfactory"

properties="

replicateasynchronously=true,

replicateputs=true,

replicateupdates=true,

replicateupdatesviacopy=false,

replicateremovals=true"/>

maxelementsinmemory="2000"

eternal="true"

overflowtodisk="false"

memorystoreevictionpolicy="lfu">

class="net.sf.ehcache.distribution.rmicachereplicatorfactory"

properties="

replicateasynchronously=true,

replicateputs=true,

replicateupdates=true,

replicateupdatesviacopy=false,

replicateremovals=true"/>

ps:

a、每个tomcat的配置文件都不一样,部署集群时有点繁琐;

b、配置cachemanagerpeerproviderfactory,rmiurls配置需要同步的各个集群节点列表(不包括本服务器节点);

上面示例配置文件是tomcat1的配置,rmiurls列表配置tomcat2,tomcat3,tomcat4需要同步的缓存项,每个缓存项的配置格式://server:port/cachename

同理,tomcat2的配置中,rmiurls列表就需要配置tomcat1,tomcat3,tomcat4的缓存项;tomcat3,tomcat4以此类推;

c、配置cachemanagerpeerlistenerfactory,本节点的缓存监听配置,属性中需指定本节点ip或域名、监听端口号、socket通信超时时间

hostname=192.168.178.101,port=40001,sockettimeoutmillis=2000

同理:tomcat2配置:hostname=192.168.178.101,port=50001,sockettimeoutmillis=2000

tomcat3配置:hostname=192.168.178.102,port=40001,sockettimeoutmillis=2000

tomcat4配置:hostname=192.168.178.102,port=50001,sockettimeoutmillis=2000

d、配置具体的cache,需要配置cacheeventlistenerfactory,指定哪些操作时需要replicatecache(同步复制缓存)

replicateputs=true|false–当一个新元素增加到缓存中的时候是否要同步复制到其他的peers.默认是true。replicateupdates=true|false–当一个已经在缓存中存在的元素被覆盖更新时是否要进行复制。默认是true。replicateremovals=true|false–当元素移除的时候是否进行复制。默认是true。replicateasynchronously=true|false–复制方式是异步的(指定为true时)还是同步的(指定为false时)。默认是true。replicateupdatesviacopy=true|false–当一个元素被拷贝到其他的cache中时是否进行复制(指定为true时为复制),默认是true。

ehcahce官方文档中的描述:

thefactoryrecognisesthefollowingproperties:

replicateputs=true|false-whethernewelementsplacedinacachearereplicatedtoothers.defaultstotrue.

replicateupdates=true|false-whethernewelementswhichoverrideanelementalreadyexistingwiththesamekeyarereplicated.defaultstotrue.

replicateremovals=true-whetherelementremovalsarereplicated.defaultstotrue.

replicateasynchronously=true|false-whetherreplicationsareasyncrhonous(true)orsynchronous(false).defaultstotrue.

replicateupdatesviacopy=true|false-whetherthenewelementsarecopiedtoothercaches(true),orwhetheraremovemessageissent.defaultstotrue.

调用ehcahe提供的api,编码缓存的加载及获取,更新

引入jar包:ehcache.jar

放入缓存的对象必须是可序列化的,即必须实现接口serializable

示例代码:

publicclassimeiwhitelistcachehelper{

privatestaticfinalstringimei_cache="imeicache";

privatestaticimeiwhitelistdaoimeidao=newimeiwhitelistdao();

privatestaticcachecache;

static{

cache=cachemanager.getinstance().getcache(imei_cache);

}

/**

*重新加载imei白名单到缓存中

*

*@throwssqlexception

*/

publicstaticvoidreloadimeiwhitelisttocache()throwssqlexception{

synchronized(cache){

cache.removeall();

listlist=imeidao.getallimeiwhitelist();

for(imeiwhitelistdtoimeiwhitelistdto:list){

elemente=newelement(imeiwhitelistdto.getimei(),imeiwhitelistdto);

cache.put(e);

}

}

}

/**

*从缓存中获取某个imei的信息。如缓存获取失败,从db中读取,再放入缓存

*

*@paramimei

*@return

*@throwssqlexception

*/

publicstaticimeiwhitelistdtogetimeiinfo(stringimei)throwssqlexception{

imeiwhitelistdtoimeiinfo=null;

synchronized(cache){

elementelement=cache.get(imei);

if(element!=null){

//system.out.println("hitcount:"+element.gethitcount());

imeiinfo=(imeiwhitelistdto)element.getobjectvalue();

}else{

imeiinfo=imeidao.getmodelbyimei(imei);

if(imeiinfo!=null){

cache.put(newelement(imeiinfo.getimei(),imeiinfo));

}

}

}

returnimeiinfo;

}

相关文章
{{ v.title }}
{{ v.description||(cleanHtml(v.content)).substr(0,100)+'···' }}
你可能感兴趣
推荐阅读 更多>
推荐商标

{{ v.name }}

{{ v.cls }}类

立即购买 联系客服