Java 本地JVM之间的通信

Java 本地JVM之间的通信,java,sockets,jvm,rmi,cajo,Java,Sockets,Jvm,Rmi,Cajo,我的问题:我可以/应该采取什么方法在本地运行的两个或多个JVM实例之间进行通信 问题的一些描述: 我正在为一个项目开发一个系统,该项目需要单独的JVM实例来将某些任务彼此完全隔离 在它运行时,“父”JVM将创建它期望执行的“子”JVM,然后将结果返回给它(以相对简单的POJO类或结构化XML数据的格式)。不应使用SysErr/SysOut/SysIn管道传输这些结果,因为子级可能已经将这些管道用作其运行的一部分 如果子JVM在特定时间内没有响应结果,则父JVM应该能够向子JVM发出信号,要求其停

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

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

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

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

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

  • 使用Java的RMI库
  • 使用套接字传输对象
  • 使用分发库,如Cajo、Hessian
<>……但我很想听听其他人在选择这些选项之前可能会考虑什么。 谢谢你在这方面的任何帮助或建议

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


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

正如您所提到的,您显然可以通过网络发送对象,但这是一件昂贵的事情,更不用说启动一个单独的JVM了

如果您只想在一个JVM中分离不同的世界,另一种方法是使用不同的类加载器加载类。ClassA@CL1!=ClassA@CL2如果它们被CL1和CL2作为同级类装入器装入

要启用classA@CL1及classA@CL2你可以有三个类加载器

  • 加载process1的CL1
  • 加载process2的CL2(与CL1中的类相同)
  • 加载通信类(POJO和服务)的CL3
现在让CL3成为CL1和CL2的父类加载器

在CL3加载的类中,您可以使用轻量级的通信发送/接收功能(发送(Pojo)/接收(Pojo)),即CL1中的类和CL2中的类之间的Pojo


在CL3中,您公开了一个静态服务,该服务使来自CL1和CL2寄存器的实现能够发送和接收POJO

似乎不再有多少人喜欢RMI了

选项:

  • 网络服务。e、 g
  • JMX。现在,这确实是一种在桌面下使用RMI的方法,但它会起作用
  • 其他IPC协议;你引用了海森的话
  • 使用套接字,甚至共享内存,滚动您自己的内存。(在父级中打开一个映射文件,然后在子级中再次打开它。您仍然需要一些东西进行同步。)
  • 值得注意的例子有ApacheAnt(它为一种或另一种目的派生各种JVM)、ApacheMaven和Tanukisoft daemonization工具包的开源变体


    就我个人而言,我很容易使用web服务,所以我倾向于用锤子把事情变成钉子。典型的JAX-WS+JAX-B或JAX-RS+JAX-B服务使用CXF只需很少的代码,并为我管理所有的数据序列化和反序列化

    如果您不能使用stdin/stdout,那么我会使用sockets。您需要在套接字之上建立某种序列化层(就像使用stdin/stdout一样),RMI是一种非常易于使用且非常有效的层

    如果您使用RMI并发现性能不够好,我会切换到一些更高效的序列化程序-有

    我不会去任何接近web服务或XML的地方。这似乎完全是浪费时间,可能比RMI花费更多的精力,提供的性能更低。

    如果要通信的数据不是很大,请尝试一下。

    我会使用本地套接字,因为它非常擅长序列化,而且非常轻量(您还可以进行远程方法调用!我现在正在使用它),但是禁用套接字断开超时


    RMI的基本工作原理是您拥有一个远程类型,并且远程类型实现一个接口。此接口是共享的。在本地计算机上,通过RMI库将接口绑定到RMI库内存中的“注入”代码,其结果是您拥有满足接口要求的东西,但能够与远程对象通信。

    尽管它是为JVM之间的潜在远程通信而设计的,我认为您会发现,这在本地JVM实例之间也非常有效


    它可能是同类型Java中性能最好、最健壮、支持最广泛的库。

    这不是对您问题的直接回答,而是对替代方案的建议。 你考虑过吗

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

    此外,您对服务质量的所有要求(响应时间等)都消失了-您只需担心服务在某个时间是上升还是下降