Spring缓存抽象 - 分布式环境

时间:2014-02-04 14:04:57

标签: java spring tomcat caching ehcache

我想在我的分布式Web应用程序中使用spring cache abstraction。

我的Web应用程序由一个Web应用程序组成,该应用程序在3个不同的tomcats上运行,并带有负载均衡器。

现在,我的问题是当另一个tomcat执行更新时,@Evict如何在所有tomcats中缓存?

春天是否支持这种事情?

谢谢!

2 个答案:

答案 0 :(得分:11)

如果是你告诉Spring使用的是EHCache,那么EHCache支持跨越不同物理服务器的多个缓存实例replication。我使用多播发现RMI Replicated Caching取得了一些成功。从一个缓存中逐出将自动在其他缓存中复制 - 同样在添加到缓存时也是如此。

就Spring配置而言,您需要设置各种配置元素和bean:

<cache:annotation-driven />

<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
    <property name="cacheManager" ref="cacheManager" />
</bean>

<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
    <property name="configLocation"  value="classpath:/ehcache.xml"/>
</bean> 

其余配置在ehcache.xml文件中完成。来自ehcache.xml的示例复制缓存可能如下所示:

<cache name="example" 
        maxElementsInMemory="1000"
        eternal="false" 
        overflowToDisk="false" 
        timeToIdleSeconds="0"
        timeToLiveSeconds="600">
        <cacheEventListenerFactory 
            class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"/>
        <bootstrapCacheLoaderFactory
            class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory"
            properties="bootstrapAsynchronously=true, maximumChunkSizeBytes=5000000"/>
</cache>

然后您需要将复制设置添加到ehcache.xml,如下所示:

<cacheManagerPeerProviderFactory
        class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
        properties="peerDiscovery=automatic, multicastGroupAddress=230.0.0.2,
                    multicastGroupPort=4455, timeToLive=1" />

<cacheManagerPeerListenerFactory
        class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
        properties="hostName=localhost, port=40001, socketTimeoutMillis=2000" />

如文档中所述,还有其他方法可以在EHCache中配置复制,但上面描述的RMI方法相对简单并且对我来说效果很好。

答案 1 :(得分:1)

您可以尝试使用群集缓存,例如Hazelcast。 Ehcache还支持通过Terracota服务器进行群集缓存。

比方说,在负载平衡的环境中,您有3个应用程序节点。如果您使用Hazelcast,则每个应用程序节点将充当hazelcast的缓存节点,并且它们在一起将为您提供单个缓存服务器的抽象。因此,每当您更新一个节点中的实体时,其他节点将立即获得通知,并在必要时更新其缓存。这样,您也不必逐出缓存的对象。

配置它也很容易,看起来像这样

        <tcp-ip enabled="true">
            <member-list>
                <member>machine1</member>
                <member>machine2</member>
                <member>machine3:5799</member>
            </member-list>
        </tcp-ip>

有关更多信息,请尝试阅读本文here