RMI和Web Services。对于Java2Java远程通信,哪个更好?

48
我对Web服务和远程方法调用(RMI)都很新奇,想知道在Java编写的不同Web应用程序之间进行远程通信时,哪种方式更好。如果这些应用程序都是用Java编写的(这就是WS的优点,不涉及不同编程语言),那么应该选择哪一种呢?
一方面,使用Web服务会带来一些性能开销(有没有人有相关数据可以证明?);另一方面,Web服务似乎更加松耦合,可以用于实现更加面向服务的体系结构(SOA),而采用RMI则不太可能做到这一点。
虽然这是一个相当普遍的问题,但您有什么看法呢?
谢谢。
9个回答

35

Web服务允许松散耦合的架构。而使用RMI,您必须确保所有应用程序实例中的类定义保持同步,这意味着即使只更改其中一个(不一定是必需的,但由于序列UUID等原因通常需要),也必须同时部署所有应用程序实例。

此外,它并不是非常可扩展的,如果您想要具有负载均衡器可能会出现问题。

在我看来,RMI最适合较小的本地应用程序,它们与互联网无关但仍需要解耦。我曾经使用它来处理电子通信的Java应用程序,并对结果感到满意。对于其他需要更复杂的部署并跨越互联网工作的应用程序,我宁愿使用Web服务。


10
为什么你认为它无法扩展,因为它不够可扩展。 - Darwin
2
点赞了上面的评论。当我们称某个东西为“不可扩展”、“不适合生产环境”或“不适用于大型应用程序”时,我们应该非常具体。 - wavicle
5
我之前提到,我认为这个问题是有问题的原因是目标类定义必须在所有部署中保持同步,这意味着你要非常小心地选择部署内容或者非常小心地扩展你的类。虽然两件事情都可行,但通常会导致错误。能做到吗?当然可以!它会起作用吗?当然会!用户会犯错误吗?十分肯定! - Mario Ortegón

13
无论您是使用Web服务还是更 "本地" 的方法取决于环境。如果您必须通过代理或一些企业防火墙(s)进行通信,则Web服务更有可能工作,因为它们仅依赖于HTTP。RMI需要您为应用程序打开另一个端口,这在某些环境中可能会很困难(虽然不是技术上的问题)...
如果您知道此问题不是问题,请考虑使用RMI。SOA不太依赖于技术,而是依赖于良好的服务设计。如果您有EJB容器,可以通过RMI调用会话bean,并且可以通过Web服务将其公开,如果确实需要。
性能取决于您计划交换的数据。如果要从一个应用程序发送复杂对象网络到另一个应用程序,则使用RMI可能更快,因为它以二进制格式传输(通常情况下)。如果您已经有某种文本/XML内容,则Web服务可能相当或甚至更快,因为此时您根本不需要转换任何内容(用于通信)。
敬祝好运, Martin

我有一个问题,文本Web服务可能比RMI甚至更快。那么,如果我们在两端都使用序列化程序/反序列化程序(例如:Jacson),会发生什么?序列化和反序列化都有成本。整体传输成本会是多少?整个过程是否比RMI更快?这是我在应用程序开发中遇到的问题。谢谢! - Janitha Madushan
讲解得很清楚,是的,当需要共享复杂对象时使用RMI。对于文本信息,请使用HTTP协议,对于易于阅读的数据,请使用REST或SOAP。 - Akash5288

11
一个有利于WS而不是RMI的因素是,WS可以在HTTP端口80/443上工作,这些端口通常不会被防火墙阻止,可以在NAT后面工作等等。 RMI具有更复杂的底层网络协议,需要您打开RMI端口,并且如果客户端被NAT,则可能无法正常工作。 其次,使用RMI会限制您的JAVA-JAVA通信,而使用Web服务则没有此类限制。 通过电线调试Web服务要容易得多,因为数据是SOAP / HTTP,可以通过嗅探工具轻松捕获以进行调试。我不知道如何通过RMI轻松完成此操作。 此外,RMI真的很古老,最近几年没有得到太多关注。在CORBA大行其道的时代,RMI和CORBA都是过时的技术。 最好的选择是REST风格的Web服务。

正如您所说,使用嗅探工具也可以被他人用来查找敏感数据传输 :) - Viswanath Lekshmanan

6

我的 RMI 和 Web Services 的经验与您上面的猜想相似。一般来说,如果通信要求是复杂对象,RMI 的性能优于 Web Services。必须明确指定 JEE 接口规范以便使用 Web Services。

请注意,Web Services 是互操作的,而 RMI 不是(就客户端和服务器的技术而言)。当我有一个或多个外部合作伙伴实施接口时,我倾向于使用 Web Services, 但是如果我控制连接的两端,则使用 RMI。


2

@Martin Klinke

"性能取决于您计划交换的数据。如果您想将复杂对象网络从一个应用程序发送到另一个应用程序,使用RMI可能会更快,因为它以二进制格式传输(通常情况下)。如果您已经有某种文本/XML内容,则Web服务可能是等效甚至更快的,因为这样您就不需要转换任何内容(进行通信)。

据我所知,在序列化-反序列化过程中,性能问题与其要交换的数据有关。我不确定这两个术语是否相同,顺便说一下。在分布式编程中,我谈论的不是在同一JVM中发生的过程,而是关于如何复制数据。它可以是按值传递或按引用传递。二进制格式对应于按值传递,这意味着将对象以二进制形式复制到远程服务器。如果您到现在还有疑问,我很乐意听取意见。

在序列化-反序列化或者编组-解组方面,以二进制格式和文本/XML内容发送之间有什么区别吗?

我只是猜测。这并不取决于您发送的数据类型。无论您发送什么数据类型,它都将成为编组-解组过程的一部分,并最终以二进制形式发送,对吧?

祝好 Hakki

"

2

如果您需要维护复杂状态,则RMI可能是更好的选择。


1
作为多年来的Spring迷和SOA倡导者,我建议使用Spring远程调用。这种服务导出器可以解决RMI的问题。
org.springframework.remoting.rmi.RmiServiceExporter

其他的传输方式当然也是可行的。如果你合理地版本化你的接口(端点)和数据传输对象(DTO),并且正确管理序列化UUID,那么序列化就是可以管理的。我们将“Alpha”、“Bravo”后缀添加到我们的接口和对象中,并在必要时增加、减少和重新发明。我们还将我们的序列化UUID固定为1,并确保更改仅为增量式,否则我们会从“Bravo”移动到“Charlie”。所有这些都可以在企业设置中管理。

1

Spring Remoting怎么样呢?它将REST-like HTTP协议与RMI的二进制格式相结合。对我来说非常完美。


-1

对于Spring Remoting(我猜你指的是HTTP Invoker),双方都应该使用Spring,如果是这种情况,可以进行讨论。

对于Java到Java应用程序,RMI是一个很好的解决方案,如果客户端不在您的控制范围内或可能移动到另一个平台,则应避免使用JAX-RPC或JAX-WS进行Java到Java通信。


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