【发布时间】:2015-03-27 15:51:09
【问题描述】:
我正在尝试使用 RMI 实现 EhCache 复制缓存。我有一个 Spring Web 应用程序,它使用 EhCache 进行数据缓存。 Ehcache 包含很少的 Java.Util.Map,用于整个应用程序视图页面。当用户从前端屏幕创建一条记录(比如一些业务 JAVA POJO 对象)时,该记录将被插入到数据库中,随后,由 EhCache 保存的 Maps 被更新。
后来,我们在同一台机器上的 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" />
在 Tomcat 实例 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);
}
我在以下方法上得到 NullPointerException
@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();
}
【问题讨论】:
-
NullPointerException 在哪一行被抛出?
-
return (List
) elementt.getObjectValue(); //这是向我抛出 NullPointerException 的行。 -
此 NullPointerException 发生在两个 tomcat 实例中。第三个,应用程序运行没有问题。相同的应用程序部署在所有三个 tomcat 实例中。
-
在给定的时间点,缓存数据仅在一个实例中可用。例如,假设我正在从 Tomcat 1 访问应用程序。Tomcat1 中的应用程序从缓存中填充页面中的数据。 Parallely,当我单独从 Tomcat 2 访问应用程序时,Tomcat 2 中的应用程序会从缓存中填充数据。但在 Tomcat 1 实例中,如果我导航到任何页面,都会收到 NullPointerException。
标签: java tomcat replication rmi ehcache