在活动的 Apache Ignite 网格中部署新应用程序版本(具有更改的会话对象)时出现 ClassNotFoundException

ClassNotFoundException while deploying new application version (with changed session object) in active Apache Ignite grid

我们目前正在将 Apache Ignite 集成到我们的应用程序中以在集群中共享会话。

此时我们可以在两个本地 tomcat 实例之间成功共享会话,但是有一个用例目前还没有用。

当 运行 两个具有完全相同代码的本地实例时,一切都很好。但是当 Ignite 逻辑集成到我们的生产集群中时,我们会遇到以下用例:

  1. 节点 1节点 2,运行应用程序的 版本 1
  2. 此时我们要部署应用程序的版本 2
  3. Tomcat停止在节点1,部署版本2,部署结束Tomcat 在 节点 1 再次启动。
  4. 我们现在有 节点 1版本 2 的代码和 节点 2,仍然使用 版本 1
  5. Tomcat停止在节点2,部署版本2,部署结束Tomcat 在 节点 2 再次启动。
  6. 我们现在有 节点 1版本 2 的代码和 节点 2版本 2
  7. 部署完成

当在同一网格中使用两个 tomcat 实例在本地再现此用例时,Ignite 网络会话集群失败。我测试的是删除位于用户会话中的 class(配置文件)中的一个 'String property'。当启动 Node 1 并更改 class 时,出现以下异常:

Caused by: java.lang.ClassNotFoundException: 
Optimized stream class checksum mismatch 
(is same version of marshalled class present on all nodes?) [expected=4981, actual=-27920, cls=class nl.package.profile.Profile]

这将是我们部署的 common/regular 用例。我的问题是:如何处理这个用例? Ignite 中有解决 resolve/workaround 此类问题的方法吗?

据我了解,您的用例非常适合 Ignite Binary 对象 [1]。 此功能允许以 class-free 格式存储对象,并在对象版本更改时在运行时修改对象结构而无需完全重启集群。

你的人 class 应该实现 org.apache.ignite.binary.Binarylizable 接口,让你完全控制序列化和反序列化逻辑。使用此接口,您甚至可以在集群中有两个节点在反序列化和序列化时使用不同版本的 Person class reading/writing 仅需要字段 from/to 二进制格式。

[1] https://apacheignite.readme.io/docs/binary-marshaller