RMI的速度有多快?

4
我看到了这个问题:两个独立Java桌面应用程序之间的通信(答案:JGroups),我正在考虑使用JavaGroups或直接RMI实现一些功能,但速度至关重要。我不会发送大量数据(MIDI消息内容,每个消息3个字节,每三毫秒不超过两条),这都在同一台机器上。 认为在同一物理机器上使用RMI / JGroups会很慢是愚蠢的吗? (我的想法是,我不能承受超过1ms的延迟,因为我已经有一些,但我不确定如何在此情况下最好地谈论速度。)
我想我的真正问题是:是否有通过比TCP/IP更快速传输的Java内部应用程序通信选项? 我指的是已经在Java中实施的内容,而不是需要我实施JNI的可能性。
我知道,不要过早优化等等,但是总比安全感觉更好。

这里荒谬的是,甚至考虑除了Socket.getOutputStream.write(byte[])以外的任何数据(由三个字节组成)传输方式。你没有对象,也没有任何明显的RPC语义,因此根本没有理由考虑其他任何方法。也许你应该考虑UDP多播。 - user207421
4个回答

6

有没有比TCP/IP更快的Java应用程序间通信选项?

据我所知,没有显著的选择。

但我认为你的想法是错误的。假设您正在传递小消息,则主要性能杀手将是调用的开销,而不是字节移动的速度。这些开销包括执行系统调用所需的时间,在客户端和服务器端切换进程上下文,处理内核中的消息数据包头以及路由数据包的时间。任何同步的RPC-like交互都需要进行调用并等待回复;即应用程序 -> 服务器 -> 往返时间。

提高吞吐量的方法是专注于以下内容:

  • 减少应用程序需要的RPC数量;例如通过组合它们使其更加粗粒度。

  • 寻找将同步交互转换为异步交互的方法;例如使用基于消息而不是基于RPC的技术。


感谢Stephen,我认为这个答案非常准确且很好。我实际上并不是在进行双向对话:一个程序将使用另一个程序来进入应用程序上下文(VST主机,对于这个虚构的术语我很抱歉),而它本身并没有运行。此外,在我特定的情况下只可能进行少量的聚合(根据所需的消息),但我认为你对于聚合和异步同步的观点是正确的。 - Dan Rosenstark

2

这个基准测试大约两年前发布,但是它显示,除了Hessian 2(我相信仍处于测试版),没有比RMI更快的流行Java远程调用解决方案。

然而,如果你的消息只有单个数字字节,使用任何远程调用解决方案似乎都有些过头了,特别是如果进程在同一台机器上。如果可能的话,我建议将它们合并到单个进程中。您也可以考虑使用普通的Java套接字


绝对没错,普通的Java套接字可能可以做到。但我担心底层的堆栈(TCP/IP?)...如果通过普通的Java套接字进行两个应用程序之间的通信,它会增加多少延迟? - Dan Rosenstark
抱歉,我没有提到:如果可以的话,我会将它们合并为一个进程。但是我不能这样做,因为其中一个将是独立应用程序,而另一个将是VST插件。 - Dan Rosenstark
1
我真的无法说使用套接字会增加多少延迟。虽然不会很多,但是当我们谈论如此小的时间单位时,我无法确定具体的预期。使用某种共享内存模型进行通信应该更快,但是我不确定如何在JNI之外实现这一点。这并不意味着没有适用的解决方案。然而,如果您的应用程序对延迟如此敏感,那似乎是一个设计缺陷。您可能希望考虑使用java.nio类的缓冲能力来帮助减轻这个问题。 - Jason Gritman
非常好的评论,感谢对话。我也猜想它会非常快。不确定现在是如何工作的,但是早些时候EJB容器通过RMI与servlet容器通信,因此在同一台机器上的网络延迟应该不会太大。 - Dan Rosenstark

2
如果速度至关重要,您应该在同一线程中进行调用。使用网络不会得到如此快的结果。
但是,假设速度并不是那么重要,您可以在大约500微秒内执行Java RMI调用,并且使用自定义编码的RPC,您可以在大约24微秒内通过环回进行调用。即使在同一JVM中的线程之间传递数据也可能需要8微秒。
您需要决定允许多少时间来进行网络调用。您还需要决定启动调用的时间是否关键,还是返回结果的时间关键。(后者的开销通常是前者的两倍)
注意:这里讨论的是微秒级别,而不是毫秒级别。对于您的目的,我会忽略任何需要花费多个毫秒的选项。

哇,我不确定当时是怎么错过这个答案的。所以RMI基本上是非常快的。 - Dan Rosenstark
@Yar 这都是相对的。0.5毫秒可能已经足够快了,这种情况下RMI可能是最佳选择。通过调整系统和JVM,您可以将套接字的往返延迟降至6微秒,在共享内存中,您可以将其降至200纳秒。 - Peter Lawrey
确实,这一切都是相对的,但是在一个用户正在与音乐程序交互的系统中仅添加一次这种延迟是完全可以接受的,假设它只是旋钮和按钮。即使对于鼓来说,只要延迟相对一致,我认为25微秒也不会被注意到。 - Dan Rosenstark
对于人类来说,任何短于1/50秒(20毫秒)的时间都是无法察觉的。一些国家的TZ屏幕更新频率为50赫兹,而一些电影院的更新频率为42赫兹,但这并不会被注意到。 - Peter Lawrey
1
@Peter Lawrey - 视觉连续性与音频成像非常不同。根据http://www.silcom.com/~aludwig/EARS.htm,低于200Hz的某些内容可能会导致明显的回声。虽然不知道这个应用程序最终会产生什么,但音频准确性非常重要。 - Jé Queue

0
在同一台物理机器上使用RMI/JGroups会很慢,这想法很愚蠢吗?
如果您的机器性能不错,那么可能是的 :) 如果您正在运行具有大量进程占用CPU等资源的机器,则情况可能会有所不同。像往常一样,了解是否会遇到与我相同的问题的最佳方法是进行测试。
以下是使用nanoTime在同一JVM中发送字符串“123”并在服务器上将其与“abc”连接以获取“123abc”并返回所需时间(以毫秒为单位)。
冷JVM:大约0.25毫秒延迟
0.250344
0.262695
0.241540
0.282461
0.301057
0.307938
0.282102

热JVM:大约0.07毫秒的延迟。

0.87916
0.72474
0.73399
0.64692
0.62488
0.59958
0.59814
0.66389

如果RMI服务器和客户端在本地运行,那么您将在1毫秒内完成。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接