EhCache + JGroups 给出“复制队列刷新异常:null”
我正在尝试使用基于 JGroups 的复制来配置 EhCache,但是一旦将第一个元素添加到缓存中,我就会收到以下异常的日志:
12061 [Replication Thread] ERROR net.sf.ehcache.distribution.RMIAsynchronousCacheReplicator - Exception on flushing of replication queue: null. Continuing...
java.lang.NullPointerException
at net.sf.ehcache.distribution.RMISynchronousCacheReplicator.listRemoteCachePeers(RMISynchronousCacheReplicator.java:335)
at net.sf.ehcache.distribution.RMIAsynchronousCacheReplicator.flushReplicationQueue(RMIAsynchronousCacheReplicator.java:299)
at net.sf.ehcache.distribution.RMIAsynchronousCacheReplicator.replicationThreadMain(RMIAsynchronousCacheReplicator.java:119)
at net.sf.ehcache.distribution.RMIAsynchronousCacheReplicator.access$100(RMIAsynchronousCacheReplicator.java:57)
at net.sf.ehcache.distribution.RMIAsynchronousCacheReplicator$ReplicationThread.run(RMIAsynchronousCacheReplicator.java:371)
ehcache.xml 如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<ehcache
updateCheck="true"
monitoring="autodetect"
defaultTransactionTimeoutInSeconds="30"
dynamicConfig="true">
<cacheManagerPeerProviderFactory
class="net.sf.ehcache.distribution.jgroups.JGroupsCacheManagerPeerProviderFactory"
properties="jgroups.xml"
/>
<defaultCache
maxElementsInMemory="200"
eternal="false"
statistics="true"
timeToIdleSeconds="86400"
timeToLiveSeconds="86400"
overflowToDisk="false">
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicateAsynchronously=true, replicatePuts=true, replicateUpdates=true, replicateUpdatesViaCopy=true, replicateRemovals=true"
/>
<bootstrapCacheLoaderFactory class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory" />
</defaultCache>
</ehcache>
jgroups.xml
是这样的:
<?xml version='1.0'?>
<config>
<TCP start_port="7800" />
<TCPPING
timeout="3000"
initial_hosts="localhost[7800],localhost[7800]"
port_range="10"
num_initial_members="2" />
<VERIFY_SUSPECT timeout="1500" />
<pbcast.NAKACK
use_mcast_xmit="false"
gc_lag="100"
retransmit_timeout="300,600,1200,2400,4800"
discard_delivered_msgs="true" />
<pbcast.STABLE
stability_delay="1000"
desired_avg_gossip="50000"
max_bytes="400000" />
<pbcast.GMS
print_local_addr="true"
join_timeout="5000"
shun="false"
view_bundling="true" />
</config>
使用jgroups版本2.8.1.GA,ehcache-core版本2.5.1,ehcache-jgroupsreplication版本1.5。
我做错了什么?
更新:当我更改为replicateAsynchronously=false
时,出现以下异常:
Exception in thread "main" java.lang.NullPointerException
at net.sf.ehcache.distribution.RMISynchronousCacheReplicator.listRemoteCachePeers(RMISynchronousCacheReplicator.java:335)
at net.sf.ehcache.distribution.RMISynchronousCacheReplicator.replicatePutNotification(RMISynchronousCacheReplicator.java:145)
at net.sf.ehcache.distribution.RMISynchronousCacheReplicator.notifyElementPut(RMISynchronousCacheReplicator.java:132)
at net.sf.ehcache.event.RegisteredEventListeners.notifyListener(RegisteredEventListeners.java:294)
at net.sf.ehcache.event.RegisteredEventListeners.invokeListener(RegisteredEventListeners.java:284)
at net.sf.ehcache.event.RegisteredEventListeners.internalNotifyElementPut(RegisteredEventListeners.java:144)
at net.sf.ehcache.event.RegisteredEventListeners.notifyElementPut(RegisteredEventListeners.java:122)
at net.sf.ehcache.Cache.notifyPutInternalListeners(Cache.java:1515)
at net.sf.ehcache.Cache.putInternal(Cache.java:1490)
at net.sf.ehcache.Cache.put(Cache.java:1417)
at net.sf.ehcache.Cache.put(Cache.java:1382)
更新2:问题是在 Terracota 的 JIRA 中创建的:https://jira.terracotta.org/jira/browse/EHC-927
I'm trying to configure EhCache with JGroups-based replication, but I get log flooded with the following exception as soon as first element is added to the cache:
12061 [Replication Thread] ERROR net.sf.ehcache.distribution.RMIAsynchronousCacheReplicator - Exception on flushing of replication queue: null. Continuing...
java.lang.NullPointerException
at net.sf.ehcache.distribution.RMISynchronousCacheReplicator.listRemoteCachePeers(RMISynchronousCacheReplicator.java:335)
at net.sf.ehcache.distribution.RMIAsynchronousCacheReplicator.flushReplicationQueue(RMIAsynchronousCacheReplicator.java:299)
at net.sf.ehcache.distribution.RMIAsynchronousCacheReplicator.replicationThreadMain(RMIAsynchronousCacheReplicator.java:119)
at net.sf.ehcache.distribution.RMIAsynchronousCacheReplicator.access$100(RMIAsynchronousCacheReplicator.java:57)
at net.sf.ehcache.distribution.RMIAsynchronousCacheReplicator$ReplicationThread.run(RMIAsynchronousCacheReplicator.java:371)
ehcache.xml is like this:
<?xml version="1.0" encoding="UTF-8"?>
<ehcache
updateCheck="true"
monitoring="autodetect"
defaultTransactionTimeoutInSeconds="30"
dynamicConfig="true">
<cacheManagerPeerProviderFactory
class="net.sf.ehcache.distribution.jgroups.JGroupsCacheManagerPeerProviderFactory"
properties="jgroups.xml"
/>
<defaultCache
maxElementsInMemory="200"
eternal="false"
statistics="true"
timeToIdleSeconds="86400"
timeToLiveSeconds="86400"
overflowToDisk="false">
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicateAsynchronously=true, replicatePuts=true, replicateUpdates=true, replicateUpdatesViaCopy=true, replicateRemovals=true"
/>
<bootstrapCacheLoaderFactory class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory" />
</defaultCache>
</ehcache>
jgroups.xml
is like this:
<?xml version='1.0'?>
<config>
<TCP start_port="7800" />
<TCPPING
timeout="3000"
initial_hosts="localhost[7800],localhost[7800]"
port_range="10"
num_initial_members="2" />
<VERIFY_SUSPECT timeout="1500" />
<pbcast.NAKACK
use_mcast_xmit="false"
gc_lag="100"
retransmit_timeout="300,600,1200,2400,4800"
discard_delivered_msgs="true" />
<pbcast.STABLE
stability_delay="1000"
desired_avg_gossip="50000"
max_bytes="400000" />
<pbcast.GMS
print_local_addr="true"
join_timeout="5000"
shun="false"
view_bundling="true" />
</config>
Using jgroups version 2.8.1.GA, ehcache-core version 2.5.1, ehcache-jgroupsreplication version 1.5.
What am I doing wrong?
UPDATE: When I change to replicateAsynchronously=false
I get the following exception:
Exception in thread "main" java.lang.NullPointerException
at net.sf.ehcache.distribution.RMISynchronousCacheReplicator.listRemoteCachePeers(RMISynchronousCacheReplicator.java:335)
at net.sf.ehcache.distribution.RMISynchronousCacheReplicator.replicatePutNotification(RMISynchronousCacheReplicator.java:145)
at net.sf.ehcache.distribution.RMISynchronousCacheReplicator.notifyElementPut(RMISynchronousCacheReplicator.java:132)
at net.sf.ehcache.event.RegisteredEventListeners.notifyListener(RegisteredEventListeners.java:294)
at net.sf.ehcache.event.RegisteredEventListeners.invokeListener(RegisteredEventListeners.java:284)
at net.sf.ehcache.event.RegisteredEventListeners.internalNotifyElementPut(RegisteredEventListeners.java:144)
at net.sf.ehcache.event.RegisteredEventListeners.notifyElementPut(RegisteredEventListeners.java:122)
at net.sf.ehcache.Cache.notifyPutInternalListeners(Cache.java:1515)
at net.sf.ehcache.Cache.putInternal(Cache.java:1490)
at net.sf.ehcache.Cache.put(Cache.java:1417)
at net.sf.ehcache.Cache.put(Cache.java:1382)
UPDATE 2: Issue is created in Terracota's JIRA: https://jira.terracotta.org/jira/browse/EHC-927
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
正如 Chris 在 EHC927 中指出的那样,我使用了错误的 cacheEventListenerFactory 类。它应该是
net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory
而不是net.sf.ehcache.distribution.RMICacheReplicatorFactory
。As pointed out by Chris in EHC927 I was using wrong cacheEventListenerFactory class. It should be
net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory
instead ofnet.sf.ehcache.distribution.RMICacheReplicatorFactory
.的源代码
我检查了 RMIAsynchronousCacheReplicator 类http://www.jarvana.com/jarvana/view/net/sf/ehcache/ehcache-core/2.1.0/ehcache-core-2.1.0-sources.jar!/net/sf /ehcache/distribution/RMIAsynchronousCacheReplicator.java?format=ok
调用
flushReplicationQueue()
时出现异常;它还应该检查replicationQueue != null
,而不仅仅是replicationQueue.size() == 0
。就像在 while 循环中测试线程的alive()
所做的那样...如果对象不存在或未初始化,它无法刷新对象...它如何知道该对象如果它不存在或未初始化,则是否为空?简单地捕获 NullPointerException 并不是告诉用户这一点的好方法!
代码的目的只是为了避免当线程在 while 循环中不执行任何操作时 CPU 空闲时间跳至 50%,如果 CPU 使用率一直在 50% 左右变化,则可能会导致用户认为 Encache 出现问题...
可能,您需要添加具有较小值(100 毫秒到 150 毫秒)的属性
asynchronousReplicationInterval
,以便可以构建复制队列。附加如下:下面的 RMIAsynchronousCacheReplicator 构造函数中可能需要它:
也许,您可以暂时忽略该问题,并让其他人报告该错误(如果它被认为是错误的话)...我想知道为什么它说“继续……”后来……
I've checked the source code for RMIAsynchronousCacheReplicator class
http://www.jarvana.com/jarvana/view/net/sf/ehcache/ehcache-core/2.1.0/ehcache-core-2.1.0-sources.jar!/net/sf/ehcache/distribution/RMIAsynchronousCacheReplicator.java?format=ok
There is something not right when
flushReplicationQueue()
is called; it should also check forreplicationQueue != null
, not justreplicationQueue.size() == 0
. Just like what it does to test the thread'salive()
in the while loop...It cannot flush an object if the object does not exist or is not initialized...how can it know the object is empty or not if it does not even exist or is not initialized? Simply catching
NullPointerException
is not a nice way tell the user about it!The intent of the code simply to avoid CPU idle time to jump to 50% when the thread does nothing in the while loop which it may lead the user to believe something is not right with Encache if the CPU usage evolves around 50% all the time...
Probably, you need to add the property
asynchronousReplicationInterval
with a small value (100 ms to 150 ms) so that replication queue can be built. Append it as follows:It may be needed in the RMIAsynchronousCacheReplicator constructor below:
Maybe, you can just ignore the problem for the time being and let someone else report the bug if it is even considered a bug...I wonder why it says "Continuing..." later...