如何让2个JVM互相交谈


71

我有以下情况:

我有2个JVM进程(实际上是2个java进程单独运行,而不是2个线程)在本地计算机上运行。我们称它们ProcessAProcessB

我希望他们彼此交流(交换数据)(例如,ProcessA发送消息ProcessB以执行某项操作)。

现在,我通过编写一个临时文件来解决此问题,并且这些过程会定期扫描此文件以获取消息。我认为这种解决方案不是很好。

什么是实现我想要的更好的选择?


同时,内存映射文件已添加到可能的方法中。
Nikolai Dmitriev

Answers:


85

IPC的多个选项:

基于套接字的(裸骨)网络

  • 不一定难,但是:
    • 可能很冗长
    • 当您编写更多代码时,可能会为错误提供更多信息。
  • 您可以依靠现有框架,例如Netty

RMI

  • 从技术上讲,这也是网络通信,但对您而言是透明的。

完善的消息传递体系结构

  • 通常也以RMI或网络通信为基础,但支持复杂的对话和工作流程
  • 对于简单的事情可能太重了
  • ActiveMQJBoss Messaging之类的框架

Java管理扩展(JMX)

  • 旨在用于JVM管理和监视,但如果您最想让一个进程查询另一进程的数据,或者如果它们不太复杂,则可以向其发送一些操作请求,这可能有助于实现所需的功能
  • 也可以通过RMI(在其他可能的协议中)工作
  • 一开始缠头并不那么简单,但实际上相当简单

文件共享/文件锁定

  • 那就是你现在正在做的
  • 这是可行的,但要处理很多问题

讯号

  • 您可以简单地向其他项目发送信号
  • 但是,它是相当有限的,并且需要您实现翻译层(尽管这可行的,但是比起任何严肃的事情来说,这一个相当疯狂的想法。

如果没有更多细节,基于裸网络的IPC方法似乎是最好的,因为它是:

  • 最可扩展的(就向您添加新功能和工作流程而言)
  • 最轻巧(就应用程序的内存占用而言)
  • 最简单(就设计而言)
  • 最具教育意义(就学习如何实施IPC而言)。(正如您在评论中提到“ socket很难”,实际上并非如此,应该是您要从事的工作)

话虽这么说,根据您的示例(仅要求其他进程执行操作),JMX对您也足够好。


请记住,当在JVM中共享对象时,JMX在处理多个类加载器时会遇到问题。铸造有问题。也许有时需要序列化/反序列化。
LppEdd

20

我在github上添加了一个名为Mappedbus的库(http://github.com/caplogic/mappedbus),该库使两个(或更多)Java进程/ JVM通过交换消息进行通信。该库使用一个内存映射文件,并利用访存和易失性读/写来同步不同的读取器和写入器。我测量了使用此库的两个进程之间的吞吐量,该吞吐量为4000万条消息/秒,平均读取/写入一条消息的延迟为25 ns。


5
如果我没记错的话,这个lib会将一些固定大小的文件映射到内存,并附加消息直到到达文件末尾,这是否意味着从文件中读取所有内容后它就死了?据我所知,它不是环形缓冲区
将于

7

您正在寻找的是inter-process communication。Java以Java RMI API的形式提供了一个简单的IPC框架。进程间通信还有其他几种机制,例如管道,套接字,消息队列(显然,这些都是概念,因此,有一些框架可以实现这些概念)。

我认为在您的情况下,Java RMI或简单的自定义套接字实现就足够了。


1
就像管道(命名管道)一样。这是最简单的方法,因为您只是读/写普通文件。
Dmitry Trifonov

@DmitryTrifonov管道仅适用于在同一JVM中运行的两个线程,这个问题专门针对2个不同的进程。
伊尼亚斯·沃

@IgnaceVau您可以扩展管道吗?我想了解更多(示例,文档)。谢谢!
LppEdd


2

我倾向于使用jGroup在进程之间形成本地集群。它适用于同一台机器,同一JVM内甚至不同服务器之间的节点(又名进程)。

一旦了解了基础知识,就可以轻松使用它,并且具有在同一JVM中实际运行两个或多个进程的选项,可以轻松轻松地测试这些进程。

如果两者都在同一台机器上,则开销和等待时间是最小的(通常,每个动作只有大约100ns以上的TCP绕行)。


1

我认为套接字可能是更好的选择。


套接字很难实现,所以我不认为这是一种简单的方法,还有其他解决方案吗?更高级别的api,框架,更易于实现。
tnk_peka 2012年

1
困难或简单取决于目的。简单地说,我不认为使用繁重的库比仅自己创建一个Socket类更有价值。
MD

0

早在2004年,我就实现了使用套接字完成这项工作的代码。在此之前,我多次寻求更好的解决方案,因为套接字方法会触发防火墙,并且我的客户会担心。到目前为止,没有更好的解决方案。客户端必须序列化您的数据,发送,服务器必须接收并反序列化。这很容易。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.