最高效 - 性能方面 - 用于 JVM 间通信

Posted

技术标签:

【中文标题】最高效 - 性能方面 - 用于 JVM 间通信【英文标题】:Most Efficient - Performance wise - for inter JVM communication 【发布时间】:2013-01-12 20:55:27 【问题描述】:

我有一个需要在不同进程之间进行通信的 Java 应用程序。进程可以运行在同一个JVM或不同的JVM,但运行在同一台机器上。

我的应用程序需要向另一个进程(相同或不同的 JVM)提交“消息”并忘记了它。类似于IBM“MQ”之类的消息队列,但简单,只使用内存,没有IO到硬盘以获得性能提升。

我不确定 Performance prescriptive 的最佳方法是什么。

我想知道 RMI 在性能方面是否高效,我认为它需要一些开销。 使用本地主机的 TCP/IP 套接字怎么样?

还有其他想法吗?

【问题讨论】:

我可以建议您在您的具体情况下测试这两种方法,然后比较结果吗? @Stephan:这将需要大量时间来实现每个方法并对其进行测试。 【参考方案1】:

我想知道 RMI 在性能方面是否有效,我认为它需要一些开销。

RMI 的工作效率很高。它做的比大多数人需要的要多得多,但通常足够快。您应该能够以大约 1 毫秒的延迟每秒获得大约 1-3 K 条消息。

使用本地主机的 TCP/IP 套接字呢?

这始终是一个选项,但使用纯 Java 序列化不会比使用 RMI 快很多。如何进行序列化和反序列化对于高性能至关重要。


重要的一点是,大部分时间都花在序列化和反序列化消息上,而大多数传输都无法帮助您,因此如果您想要获得最佳性能,您必须考虑一种有效的编组策略。大多数传输协议仅对原始字节进行基准测试。

具有讽刺意味的是,如果您愿意使用磁盘,它可能比 TCP 或 UDP(如 ZeroMQ)更快,而且您可以“免费”获得持久性。

这个库(我是作者)每秒可以在进程之间执行数百万条消息,延迟低至 100 纳秒(比 ZeroMQ 低 350 倍)https://github.com/peter-lawrey/Java-Chronicle 优点是

超快的序列化和反序列化,大多数传输基准都避免包含这一点,因为它通常需要比传输成本更长的时间。 是您可以在消息发送后随时监控队列之间发生的情况。 重播所有消息。 生产者可以在您的消费者之前处理任何数量的数据,以优雅地处理微突发,直至您的磁盘空间大小。例如消费者可能落后于 TB。 支持通过 TCP 进行复制。 消费者或生产者的重启在很大程度上是透明的。

【讨论】:

感谢#Peter 非常有帮助的回答。但是,我很难理解像您这样使用持久性(写入硬盘)的 MQ 为何比 ZeroMQ 等内存 MQ 的性能更好。 ZeroMQ 仍然使用系统调用,这些都需要时间。尤其是如果您在内核中添加大约 10 - 30 微秒的延迟。通过在进程之间共享内存映射文件,消息可以从一个进程传递到另一个进程,而无需系统调用或涉及内核。必须进行一些系统调用才能增大文件,但默认情况下是每 128 MB 一次。 谢谢...更多问题,我知道如果我使用普通的 Java 套接字,我可以使用 ObjectInputStream-ObjectOutputStream 进行序列化。如果是这样,为什么还有人去 Java RMI。 使用 RMI 或 RPC,您可以调用远程对象。这意味着您可以拨打rmiObject.method(a, b, 125);,就好像它是您本地的一样。如果你只传递一个对象,你仍然需要决定如何处理它。【参考方案2】:

如果您正在开发服务器应用程序,请尝试考虑 ZeroMQ。它具有出色的性能,允许更轻松地构建进程间通信,允许构建异步 API。

ZeroMQ 宣称 InterProcess 通信的出色性能。 Even better 比 TCP 听起来很棒。我们正在为我们的集群化架构考虑这个解决方案。

Pieter Hintjens 给出great answer 用于不同 Message Broker 之间的性能比较。

【讨论】:

以上是关于最高效 - 性能方面 - 用于 JVM 间通信的主要内容,如果未能解决你的问题,请参考以下文章

[ Linux ] 进程间通信介绍 管道

在 C++/Qt 中用于高效套接字通信的数据格式 [关闭]

Python多线程入门指南

Linux进程间通信总结

Linux进程间通信总结

Linux进程间通信总结