【问题标题】:Spring cache abstraction - distributed environmentSpring缓存抽象——分布式环境
【发布时间】:2014-02-28 13:12:44
【问题描述】:

我想在我的分布式 Web 应用程序中使用 Spring 缓存抽象。

我的 Web 应用程序在 3 个带有负载平衡器的不同 tomcat 上运行。

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

spring 支持这种东西吗?

谢谢!

【问题讨论】:

    标签: java spring tomcat caching ehcache


    【解决方案1】:

    如果您告诉 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 方法相对简单,对我来说效果很好。

    【讨论】:

    • 此配置是否使整个更新对象无效或通过多播发送整个更新对象?
    • 组播仅用于对等点发现。复制是使用点对点 RMI 实现的。如果您无法使用多播进行对等发现,则可以使用其他机制(例如在配置中手动指定服务器的 IP 地址)。
    • 谢谢,最后一个问题,从一个缓存到另一个缓存的 RMI 无效消息是阻塞还是异步发生?
    • 默认情况下它是异步的 - 但如果您希望它是同步的,那么您可以在侦听器工厂属性中设置replicateAsynchronously=false。值得查看the docs 了解更多详情。
    • 更新:今天成功配置缓存,下周测试
    【解决方案2】:

    您可以尝试使用集群缓存,例如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

    【讨论】:

      猜你喜欢
      • 2015-03-15
      • 1970-01-01
      • 1970-01-01
      • 2018-12-05
      • 2016-06-04
      • 2012-05-23
      • 1970-01-01
      • 2013-01-12
      • 2021-11-16
      相关资源
      最近更新 更多