使用 RMI EhCache 数据的复制缓存不会在所有 Tomcat 实例中加载



我正在尝试使用 RMI 实现 EhCache 复制缓存。 我有一个Spring Web应用程序,它使用EhCache进行数据缓存。Ehcache拥有很少的Java.Util.Map,这些Java.Util.Map在整个应用程序视图页面中使用。当用户从前端屏幕创建记录(例如某个业务JAVA POJO对象)时,该记录将入到数据库中,随后,EhCache持有的地图将被更新。

后来,我们在同一台机器的 3 个 tomcat 实例中部署了此 Web 应用程序。应用程序可通过 Apache HTTP 负载均衡器访问。

我面临的问题是,EhCache 数据正在一个 tomcat 实例上加载。 但其他两个则不然。 当使用端口号单独访问应用程序时,应用程序运行良好。

同样的Spring Web应用程序在Tomcat实例(9001,9002,9003)上运行。 配置为侦听的 EhCache RMI (4001、4002、4003)。

请找到我配置的 ehCache.xml 文件,

在 Tomcat 实例 1 上

<?xml version="1.0" encoding="UTF-8"?>
<ehcache name="WidgetCache" updateCheck="false">
<defaultCache maxElementsInMemory="10000" eternal="false"
    timeToIdleSeconds="0" timeToLiveSeconds="0" overflowToDisk="true"
    diskPersistent="false" diskExpiryThreadIntervalSeconds="120"
    memoryStoreEvictionPolicy="LRU" />
<cacheManagerPeerListenerFactory
    class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
    properties="hostName=10.237.31.33, port=40001, socketTimeoutMillis=2000" />
<cacheManagerPeerProviderFactory
    class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
    properties="peerDiscovery=manual, 
    rmiUrls=//10.237.31.33:40002/widgets|//10.237.31.33:40002/lobCache|//10.237.31.33:40002/lobFilterCache|//10.237.31.33:40002/glossarylobFilterCache|//10.237.31.33:40002/bbpUserListCache|//10.237.31.33:40002/userRoleCache|//10.237.31.33:40002/glossary|//10.237.31.33:40003/widgets|//10.237.31.33:40003/lobCache|//10.237.31.33:40003/lobFilterCache|//10.237.31.33:40003/glossarylobFilterCache|//10.237.31.33:40003/bbpUserListCache|//10.237.31.33:40003/userRoleCache|//10.237.31.33:40003/glossary" />

<cache name="userRoleCache" maxElementsInMemory="100" eternal="false"
    timeToIdleSeconds="0" timeToLiveSeconds="0" memoryStoreEvictionPolicy="LFU">
    <cacheEventListenerFactory
        class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
        properties="replicateAsynchronously=true, replicatePuts=true, replicateUpdates=true,replicateUpdatesViaCopy=false, replicateRemovals=true" />
</cache>
<diskStore path="java.io.tmpdir" />

在雄猫实例 2 上

<?xml version="1.0" encoding="UTF-8"?>
<ehcache name="WidgetCache" updateCheck="false">
<defaultCache maxElementsInMemory="10000" eternal="false"
    timeToIdleSeconds="0" timeToLiveSeconds="0" overflowToDisk="true"
    diskPersistent="false" diskExpiryThreadIntervalSeconds="120"
    memoryStoreEvictionPolicy="LRU" />
<cacheManagerPeerListenerFactory
    class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
    properties="hostName=10.237.31.33, port=40002, socketTimeoutMillis=2000" />
<cacheManagerPeerProviderFactory
    class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
    properties="peerDiscovery=manual, 
    rmiUrls=//10.237.31.33:40001/widgets|//10.237.31.33:40001/lobCache|//10.237.31.33:40001/lobFilterCache|//10.237.31.33:40001/glossarylobFilterCache|//10.237.31.33:40001/bbpUserListCache|//10.237.31.33:40001/userRoleCache|//10.237.31.33:40001/glossary|//10.237.31.33:40003/widgets|//10.237.31.33:40003/lobCache|//10.237.31.33:40003/lobFilterCache|//10.237.31.33:40003/glossarylobFilterCache|//10.237.31.33:40003/bbpUserListCache|//10.237.31.33:40003/userRoleCache|//10.237.31.33:40003/glossary" />
<cache name="userRoleCache" maxElementsInMemory="100" eternal="false"
    timeToIdleSeconds="0" timeToLiveSeconds="0" memoryStoreEvictionPolicy="LFU">
    <cacheEventListenerFactory
        class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
        properties="replicateAsynchronously=true, replicatePuts=true, replicateUpdates=true,replicateUpdatesViaCopy=false, replicateRemovals=true" />
</cache>
<diskStore path="java.io.tmpdir" />

在 Tomcat 实例 3 上

<?xml version="1.0" encoding="UTF-8"?>
<ehcache name="WidgetCache" updateCheck="false">
<defaultCache maxElementsInMemory="10000" eternal="false"
    timeToIdleSeconds="0" timeToLiveSeconds="0" overflowToDisk="true"
    diskPersistent="false" diskExpiryThreadIntervalSeconds="120"
    memoryStoreEvictionPolicy="LRU" />
<cacheManagerPeerListenerFactory
    class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
    properties="hostName=10.237.31.33, port=40003, socketTimeoutMillis=2000" />
<cacheManagerPeerProviderFactory
    class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
    properties="peerDiscovery=manual, 
    rmiUrls=//10.237.31.33:40001/widgets|//10.237.31.33:40001/lobCache|//10.237.31.33:40001/lobFilterCache|//10.237.31.33:40001/glossarylobFilterCache|//10.237.31.33:40001/bbpUserListCache|//10.237.31.33:40001/userRoleCache|//10.237.31.33:40001/glossary|//10.237.31.33:40002/widgets|//10.237.31.33:40002/lobCache|//10.237.31.33:40002/lobFilterCache|//10.237.31.33:40002/glossarylobFilterCache|//10.237.31.33:40002/bbpUserListCache|//10.237.31.33:40002/userRoleCache|//10.237.31.33:40002/glossary" />

<cache name="userRoleCache" maxElementsInMemory="100" eternal="false"
    timeToIdleSeconds="0" timeToLiveSeconds="0" memoryStoreEvictionPolicy="LFU">
    <cacheEventListenerFactory
        class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
        properties="replicateAsynchronously=true, replicatePuts=true, replicateUpdates=true,replicateUpdatesViaCopy=false, replicateRemovals=true" />
</cache>
<diskStore path="java.io.tmpdir" />

请告知我在这里缺少什么。

下面在 spring-servlet 中配置.xml

<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cache-manager-ref="ehcache" />
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" 
p:config-location="classpath:ehcache.xml" p:shared="true"/>

从Java商务舱

public class PortfolioUserDetailsServiceImpl implements PortfolioUserDetailsService {
private Logger logger = LoggerFactory
    .getLogger(PortfolioUserDetailsServiceImpl.class);
private UserDao userDao;
@Autowired
private CacheManager cacheManager;
private Ehcache userRoleCache;

@PostConstruct
public void init() {
 // Load our widgets cache:
userRoleCache = cacheManager.getEhcache("userRoleCache");
// Create an EHCache Element to hold the widget
Element element = new Element("getAllRoles", userDao.getAllRoles());
// Add the element to the cache
userRoleCache.put(element);
}

我在以下方法上收到空指针异常

@Override
public List<BbpUser> loadUsersfromUserListCache() throws InventoryException {
    // TODO Auto-generated method stub
    Cache cache = cacheManager.getCache("userRoleCache");
    Element elementt = cache.get("getAllRoles");
    return (List<BbpUser>) elementt.getObjectValue();
}

当 replicaUpdatesViaCopy 设置为 false 时,条目将从其他实例的缓存中删除。您需要检查 null 并从数据存储(或具有最新值的任何位置)加载它。

您可以将 replicaUpdatesViaCopy 设置为 true,并检查在访问其他实例时是否仍然获得 NPE。

有关完整的详细信息,您可以浏览 http://www.ehcache.org/generated/2.10.0/html/ehc-all/index.html#page/Ehcache_Documentation_Set/co-rmi_configuring_cache_replicators.html

最新更新