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

  • Tomcat集群部署情况说明

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

server1    192.168.178.101    

                tomcat1    tomcat2

server2    192.168.178.102    

                tomcat3    tomcat4

  • 采用Ehcache的RMI方式来实现缓存同步复制

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

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">

    <cacheManagerPeerProviderFactory

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

        properties="peerDiscovery=automatic,

        multicastGroupAddress=230.0.0.1,

        multicastGroupPort=4446

        timeToLive=1"/>

    <cacheManagerPeerListenerFactory

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

    <cache name="Cache1" 

        maxElementsInMemory="100" 

        eternal="true" 

        overflowToDisk="false" 

        memoryStoreEvictionPolicy="LFU">

        <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"/>

    </cache>       

</ehcache>


PS:

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

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

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

0是限制在同一个服务器

1是限制在同一个子网

32是限制在同一个网站

64是限制在同一个region

128是限制在同一个大洲

255是不限制

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

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

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


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

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">

    <!--RMI方式二:手动成员发现配置: ip + 端口号,手动指定需要同步的server和cache name -->

    <cacheManagerPeerProviderFactory

        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"/>

    <cacheManagerPeerListenerFactory 

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

        properties="hostName=192.168.178.101, port=40001, socketTimeoutMillis=2000" />

    <cache name="Cache1" 

        maxElementsInMemory="1000" 

        eternal="true" 

        overflowToDisk="false" 

        memoryStoreEvictionPolicy="LFU">

        <cacheEventListenerFactory

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

               properties="

               replicateAsynchronously=true, 

            replicatePuts=true, 

            replicateUpdates=true,

            replicateUpdatesViaCopy=false, 

            replicateRemovals=true"/>

        <!-- 用于在初始化缓存,以及自动设置 -->

        <bootstrapCacheLoaderFactory class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory"/>

    </cache>

    <cache name="Cache2" 

        maxElementsInMemory="2000" 

        eternal="true" 

        overflowToDisk="false" 

        memoryStoreEvictionPolicy="LFU"> 

        <cacheEventListenerFactory

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

            properties="

            replicateAsynchronously=true, 

            replicatePuts=true, 

            replicateUpdates=true,

            replicateUpdatesViaCopy=false, 

            replicateRemovals=true"/>

        <!-- 用于在初始化缓存,以及自动设置 -->

        <bootstrapCacheLoaderFactory class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory"/>

    </cache>

</ehcache> 


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,指定哪些操作时需要replicate cache(同步复制缓存)

    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官方文档中的描述:

    The factory recognises the following properties:

    replicatePuts=true | false - whether new elements placed in a cache are replicated to others. Defaults to true.

    replicateUpdates=true | false - whether new elements which override an element already existing with the same key are replicated. Defaults to true.

    replicateRemovals=true - whether element removals are replicated. Defaults to true.

    replicateAsynchronously=true | false - whether replications are asyncrhonous (true) or synchronous (false). Defaults to true.

    replicateUpdatesViaCopy=true | false - whether the new elements are copied to other caches (true), or whether a remove message is sent. Defaults to true.


  • 调用Ehcahe提供的API,编码缓存的加载及获取,更新              

引入jar包:ehcache.jar

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


示例代码:


public class ImeiWhiteListCacheHelper {

    private static final String     IMEI_CACHE = "IMEICache";

    private static ImeiWhiteListDAO imeiDao    = new ImeiWhiteListDAO();

    private static Cache            cache;

    static {

        cache = CacheManager.getInstance().getCache(IMEI_CACHE);

    }

    /**

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

     * 

     * @throws SQLException

     */

    public static void reloadImeiWhiteListToCache() throws SQLException{

        synchronized (cache) {

            cache.removeAll();

            List<ImeiWhiteListDTO> list = imeiDao.getAllImeiWhiteList();

            for ( ImeiWhiteListDTO imeiWhiteListDTO : list ) {

                Element e = new Element(imeiWhiteListDTO.getImei(),imeiWhiteListDTO);

                cache.put(e);

            }

        }

    }

    /**

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

     * 

     * @param imei

     * @return

     * @throws SQLException

     */

    public static ImeiWhiteListDTO getImeiInfo(String imei) throws SQLException{

        ImeiWhiteListDTO imeiInfo = null;

        synchronized (cache) {

            Element element = cache.get(imei);

            if (element != null) {

                // System.out.println("hit count:" + element.getHitCount());

                imeiInfo = (ImeiWhiteListDTO) element.getObjectValue();

            } else {

                imeiInfo = imeiDao.getModelByIMEI(imei);

                if (imeiInfo != null) {

                    cache.put(new Element(imeiInfo.getImei(),imeiInfo));

                }

            }

        }

        return imeiInfo;

    }



转载于:https://my.oschina.net/daoyouli/blog/532114

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值