本地 JVM 之间的通信

2022-09-01 17:33:37

我的问题:我可以/应该采取什么方法在本地运行的两个或多个 JVM 实例之间进行通信?

对这个问题的一些描述:
我正在为一个项目开发一个系统,该项目需要单独的JVM实例来完全隔离某些任务。

在它正在运行的过程中,“父”JVM将创建它期望执行的“子”JVM,然后返回结果(以相对简单的POJO类的格式,或者可能是结构化的XML数据)。不应使用 SysErr/SysOut/SysIn 管道传输这些结果,因为子级可能已经使用这些结果作为其运行的一部分。

如果子 JVM 在一定时间内没有响应结果,则父 JVM 应该能够向子 JVM 发出停止处理或终止子进程的信号。否则,子 JVM 应在完成其任务结束时正常退出。

到目前为止的研究:
我知道有许多技术可能有用,例如......

  • 使用 Java 的 RMI 库
  • 使用套接字传输对象
  • 使用分发库,如Cajo,Hessian

...但我有兴趣听听其他人在追求这些选项之一或任何其他选项之前可能会考虑的方法。

感谢您对此的任何帮助或建议!

编辑:
要传输的数据量 - 相对较小,它主要只是少数POJO包含表示子执行结果的字符串。如果任何解决方案在大量信息上效率低下,那么这在我的系统中不太可能成为问题。转移的金额应该是静态的,因此不必是可扩展的。

传输的延迟 - 在这种情况下不是一个关键问题,尽管如果需要对结果进行任何“轮询”,这应该能够相当频繁,而不会产生明显的开销,因此我可以在以后(例如进度条)在此基础上维护响应式GUI


答案 1

不是直接回答你的问题,而是建议一个替代方案。你有没有考虑过OSGI

它允许您在同一 jvm 中以完全隔离的方式运行 Java 项目。它的美妙之处在于,项目之间的沟通非常容易与服务(参见核心规范PDF第123页)。这样就不会进行任何形式的“序列化”,因为数据和调用都在同一个jvm中。

此外,您对服务质量的所有要求(响应时间等)都会消失 - 您只需要担心服务在您想要使用它时是向上还是向下。为此,您有一个非常好的规范,可以为您执行此操作,称为声明性服务(请参阅企业规范PDF第141页)

很抱歉这个偏离主题的答案,但我认为其他人可能会认为这是一种替代方案。

更新

为了回答您关于安全性的问题,我从未考虑过这种情况。我不相信有办法在OSGI中强制使用“内存”。

但是,有一种方法可以在JVM之外的不同OSGI运行时之间进行通信。它被称为远程服务(请参阅企业规范 PDF,第 7 页)。他们也很好地讨论了在做这样的事情时要考虑的因素(见13.1谬误)。

Apache Felix(OSGI的实现)的人我认为可以使用iPOJO实现它,称为带有iPOJO的分布式服务(他们的包装器,使使用服务更容易)。我从来没有用过这个 - 所以如果我错了,请忽略我。


答案 2

我会将KryoNet与本地套接字一起使用,因为它非常专注于序列化并且非常轻量级(您还可以获得远程方法调用!我现在正在使用它),但禁用套接字断开连接超时。

RMI 基本上基于以下原则工作:您具有远程类型,并且远程类型实现接口。此接口是共享的。在本地计算机上,通过 RMI 库将接口绑定到从 RMI 库“注入”内存中的代码,结果是您具有满足接口但能够与远程对象通信的内容。


推荐