【发布时间】:2014-02-28 13:12:44
【问题描述】:
我想在我的分布式 Web 应用程序中使用 Spring 缓存抽象。
我的 Web 应用程序在 3 个带有负载平衡器的不同 tomcat 上运行。
现在,我的问题是,当另一个 tomcat 执行更新时,我如何在所有 tomcat 中进行@Evict 缓存?
spring 支持这种东西吗?
谢谢!
【问题讨论】:
标签: java spring tomcat caching ehcache
我想在我的分布式 Web 应用程序中使用 Spring 缓存抽象。
我的 Web 应用程序在 3 个带有负载平衡器的不同 tomcat 上运行。
现在,我的问题是,当另一个 tomcat 执行更新时,我如何在所有 tomcat 中进行@Evict 缓存?
spring 支持这种东西吗?
谢谢!
【问题讨论】:
标签: java spring tomcat caching ehcache
如果您告诉 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 方法相对简单,对我来说效果很好。
【讨论】:
replicateAsynchronously=false。值得查看the docs 了解更多详情。
您可以尝试使用集群缓存,例如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。
【讨论】: