我目前正在研究以下问题,该问题发生在我们的高负荷项目中:
class org.apache.ignite.IgniteDeploymentException: Failed to deploy user message: java.nio.HeapByteBuffer[pos=0 lim=180 cap=180]
at org.apache.ignite.internal.util.IgniteUtils$8.apply(IgniteUtils.java:825)
at org.apache.ignite.internal.util.IgniteUtils$8.apply(IgniteUtils.java:823)
at org.apache.ignite.internal.util.IgniteUtils.convertException(IgniteUtils.java:944)
at org.apache.ignite.internal.IgniteMessagingImpl.send0(IgniteMessagingImpl.java:106)
at org.apache.ignite.internal.IgniteMessagingImpl.send(IgniteMessagingImpl.java:82)
...
Caused by: class org.apache.ignite.internal.IgniteDeploymentCheckedException: Failed to deploy user message: java.nio.HeapByteBuffer[pos=0 lim=180 cap=180]
at org.apache.ignite.internal.managers.communication.GridIoManager.sendUserMessage(GridIoManager.java:1571)
at org.apache.ignite.internal.IgniteMessagingImpl.send0(IgniteMessagingImpl.java:103)
... 25 more
简而言之,案例如下:
-
三个节点上的分布式缓存,所有节点都在一个工作站上运行(在此测试中);
-
每个节点上的 Worker ;
-
工作之间的消息传递是使用IgniteMessaging完成的(主题具有String的类型,我已经尝试了byte []和ByteBuffer作为消息类);
-
客户端连接到群集并触发一些业务逻辑,从而导致跨节点消息传递和扫描查询 . 查询和消息传递正在同时执行 .
我们使用具有连续部署模式的对等类加载(问题与共享模式相同) . 根据Ignite文档,只有在版本更改时才应重新部署类,但它似乎不起作用 .
我在日志中注意到很多类似的消息:
2017-05-05 13:31:28 INFO org.apache.ignite.logger.java.JavaLogger info Removed undeployed class: GridDeployment [ts=1493980288578, depMode=CONTINUOUS, clsLdr=WebAppClassLoader=MyApp@38815daa, clsLdrId=36c3828db51-0d65e7d5-77bf-444d-9b8b-d18bde94ad13, userVer=0, loc=true, sampleClsName=java.lang.String, pendingUndeploy=false, undeployed=true, usage=0]
...
2017-05-05 13:31:29 INFO org.apache.ignite.logger.java.JavaLogger info Removed undeployed class: GridDeployment [ts=1493980289125, depMode=CONTINUOUS, clsLdr=WebAppClassLoader=MyApp@355f6680, clsLdrId=1dd3828db51-1b20df7a-a98d-45a3-8ab6-e5d229945830, userVer=0, loc=true, sampleClsName=java.lang.String, pendingUndeploy=false, undeployed=true, usage=0]
...
这是我使用ByteBuffer作为消息类型的时候 . 在byte []的情况下,B级[正在不断重新部署 .
我对Ignite内核进行了一些分析,并怀疑是否在类加载器中的所有类中触发了undeploy,而至少有一个驻留在该类加载器中的类在其他加载器中重新部署 .
它发生在org.apache.ignite.spi.deployment.local.LocalDeploymentSpi #register内
-
首先,我们使用LocalDeploymentSpi #addResource获得"Map of new resources added for registered class loader" .
-
然后我们"Remove resources for all class loaders except {@code ignoreClsLdr}."使用LocalDeploymentSpi #removeResources . 在此方法中,看起来我们将包含旧版本新资源的所有加载器添加到"doomed"集合中 .
-
最后,我们迭代这个集合并为每个元素调用onClassLoaderReleased . 后一个操作实际上导致所有类都被取消部署(最终导致"Removed undeployed class"消息) .
我不明白这个概念 . 为什么有多个类加载器?为什么我们在这种情况下取消部署整个类加载器?
我很感激,如果有人能解释一下,对等类加载如何在Ignite“引擎盖下”工作 .
附:我正在查看Ignite 2.1.0的新快照的来源,但行为与标准的Ignite 1.9.0相同 .
1 回答
这在Apache Ignite用户邮件列表中讨论:http://apache-ignite-users.70518.x6.nabble.com/Understanding-the-mechanics-of-peer-class-loading-td12661.html