0

我有 2 个启用存储的缓存节点,我试图将它们用于预加载缓存。这 2 个启用存储的节点将加载大约 100 万个帐户。键和值都是String我试图写入缓存的对象。我正在使用InvocationService.execute()异步调用预加载任务的方法:

for (Map.Entry<Member, LoaderInvocable> entry : mappedWork.entrySet()) {
    Member member = entry.getKey();
    LoaderInvocable task = entry.getValue();
    invocationService.execute(task, Collections.singleton(member), null);
}

LoaderInvocable是一个实现InvocableSerializable接口的类,它的run()方法已被重写以执行从数据库读取和写入缓存的实际工作。

InvocationService在 coherence 配置文件中定义如下:

<invocation-scheme>
      <scheme-name>
      InvocationScheme</scheme-name>
      <service-name>
      LoaderInvocationService</service-name>
      <autostart system-property="tangosol.coherence.invocation.autostart">true</autostart>
 </invocation-scheme>   

以下是我得到的例外:

2016-02-22 17:16:24,612 [pool-1-thread-1] ERROR (support.context.SessionExecutable) Caught exception from SessionExecutable.execute()
(Wrapped) java.io.NotSerializableException: com.oracle.common.collections.ConcurrentLinkedQueue
    at com.tangosol.util.Base.ensureRuntimeException(Base.java:289)
    at com.tangosol.util.Base.ensureRuntimeException(Base.java:270)
    at com.tangosol.coherence.component.util.daemon.queueProcessor.packetProcessor.PacketPublisher.packetizeMessage(PacketPublisher.CDB:28)
    at com.tangosol.coherence.component.util.daemon.queueProcessor.packetProcessor.PacketPublisher$InQueue.add(PacketPublisher.CDB:8)
    at com.tangosol.coherence.component.util.daemon.queueProcessor.packetProcessor.PacketPublisher.post(PacketPublisher.CDB:1)
    at com.tangosol.coherence.component.net.Message.dispatch(Message.CDB:77)
    at com.tangosol.coherence.component.net.Message.post(Message.CDB:1)
    at com.tangosol.coherence.component.util.daemon.queueProcessor.service.Grid.post(Grid.CDB:2)
    at com.tangosol.coherence.component.util.daemon.queueProcessor.service.Grid.send(Grid.CDB:1)
    at com.tangosol.coherence.component.util.daemon.queueProcessor.service.grid.InvocationService.execute(InvocationService.CDB:33)
    at com.tangosol.coherence.component.util.safeService.SafeInvocationService.execute(SafeInvocationService.CDB:1)

. . . . . .

Caused by: java.io.NotSerializableException: com.oracle.common.collections.ConcurrentLinkedQueue
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1180)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1493)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
    at java.util.Hashtable.writeObject(Hashtable.java:988)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:975)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)
    at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:438)
    at com.tangosol.coherence.Component.writeObject(Component.CDB:1)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:975)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)
    at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:438)
    at com.tangosol.coherence.Component.writeObject(Component.CDB:1)

似乎已经成功缓存了一半的帐户。它可以是节点特定的问题吗?两个启用存储的缓存节点都位于使用相同集群配置的同一台服务器上。从日志中可以清楚地看出,两个节点都成功地加入了集群。

4

1 回答 1

0

谢谢普拉文。我已经实现了PortableObject界面并且不再面对NotSerializableException。但现在我面临一个新问题。第二个节点没有调用任务并在日志中没有任何异常离开集群。

我使用了InvocationObserver其中的提示memberLeft()集群。我的序列化实现readExternal()writeExternal()方法可能有问题吗?下面是实现:

@Override
public void readExternal(PofReader paramPofReader) throws IOException {
    // TODO Auto-generated method stub

    cacheName = paramPofReader.readString(0);
    firstRow = paramPofReader.readLong(1);
    lastRow = paramPofReader.readLong(2);

}

@Override
public void writeExternal(PofWriter paramPofWriter) throws IOException {
    // TODO Auto-generated method stub
    paramPofWriter.writeString(0, cacheName);
    paramPofWriter.writeLong(1, firstRow);
    paramPofWriter.writeLong(2, lastRow);
}
于 2016-02-25T10:21:09.710 回答