人们为什么使用 RMI,或者我什么时候应该使用 RMI?我在 oracle 的网站上阅读了有关 RMI 的那些教程。但它没有提供足够的实际例子。
据我了解,软件的模块应尽可能“不相关且分离”。在我看来,RMI 似乎是高耦合的一个例子。为什么这不是一个糟糕的编码实践?我认为客户端应该只触发指令,而对象的所有实际操作都是由服务器完成的。
人们为什么使用 RMI,或者我什么时候应该使用 RMI?我在 oracle 的网站上阅读了有关 RMI 的那些教程。但它没有提供足够的实际例子。
据我了解,软件的模块应尽可能“不相关且分离”。在我看来,RMI 似乎是高耦合的一个例子。为什么这不是一个糟糕的编码实践?我认为客户端应该只触发指令,而对象的所有实际操作都是由服务器完成的。
您真的不应该将 RMI 用于您今天构建的任何应用程序,主要是出于您刚刚列出的原因。
在某些情况下(潜入遗留或“企业”应用程序)您别无选择。
但是,如果您要开始一个新项目,其他选项包括:
与远程服务通信的事实标准。它最大的优点是重量轻,易于掌握概念。
从理论上讲,它应该比 RMI 需要更多的工作,因为您必须手动制作可用的 URL、每个 URL 中接受的动词等。在实践中,我会说 RMI 的样板文件并不能真正帮助任何人。
坚持使用 java,Jersey 是一个出色的库,可以编写您自己的 RESTful Web 服务。
如果您想要一个包含电池的解决方案,用于使用 java 的 RESTful Web 服务, Yammer 的好人的Dropwizard为您提供了一个完整的服务器和框架,准备好插入您的业务逻辑,并提供日志记录、数据库连接、序列化、请求路由和甚至是开箱即用的指标。
与远程服务通信的先前标准。除非你有理由使用它,否则我会坚持使用 REST。
Thrift 将创建一个客户端和一个服务器存根,基本上完成大部分工作。通信采用高效的二进制协议。它在 Java 世界中越来越受欢迎,因为它被“大数据”领域的许多开源项目使用。例如,Cassandra、HBase(切换到 Avro)。Scrooge 是一个 twitter 项目,用于为 scala 创建惯用的 thrift 存根。
Akka 是为 Scala 和 Java实现Actor 模型的框架。包括服务间通信的规定,并处理许多底层细节。我
根据您的需要,有些会比其他的更合适。
任何时候你有一个功能需要一些大型集中计算能力或一些昂贵的资源(例如一个巨大的数据库),但你的输出需要在许多地方无法部署这样的工作负载,那么你会查看远程方法调用. 考虑一下网络,您的桌面上没有 Google 的副本来进行您可能想要计算的任何搜索,您在需要结果的那一刻远程调用 Google 的服务器。RMI 是一种协议/系统,用于跨服务器分发您的应用程序并分离出需要访问该代码结果的客户端。
RMI 还可以作为保护应用程序各个方面的一种方式(如专有算法)。RMI 不是唯一的方法,您还可以使用 HTTP、SOAP 等。许多其他方法提供了其他功能,例如真正的语言透明性、更简单和更有效的实现以及更好的解耦。
在 Java 编程语言中支持分布式对象的目标是:
- 支持对不同虚拟机中对象的无缝远程调用
- 支持从服务器到小程序的回调
- 以自然的方式将分布式对象模型集成到 Java 编程语言中,同时保留大部分 Java 编程语言的对象语义
- 使分布式对象模型和本地 Java 平台的对象模型之间的差异变得明显
- 使编写可靠的分布式应用程序尽可能简单
- 保留 Java 平台的运行时环境提供的类型安全性
- 支持远程对象的各种引用语义;例如实时(非持久)引用、持久引用和延迟激活
- 维护由安全管理器和类加载器提供的 Java 平台的安全环境 所有这些目标的基本要求是 RMI 模型既简单(易于使用)又自然(非常适合该语言)。
你是对的,RMI 是服务提供者和服务消费者之间过于紧密耦合的一个例子。而且它比乍看起来更糟糕:您永远不知道您可能会被推送到客户端,从而ClassNotFoundException
掩盖了发生的真正错误。RMI 和类似的 EJB 是过去的技术,过去相信“透明分布的对象”的错觉。
今天的远程服务基于与 RMI 方法完全相反的方法:REST 和 JSON。
RMI 是针对完全相反的情况,在这种情况下,您需要紧密绑定,紧密到看起来像是一个本地方法调用。如果您不想要,请不要使用它。整个 RPC 范式并不适合所有人,包括我,即使我写了一本关于 RMI 的书,但每个工具都有其用途。例如,Java EE 是基于 RMI 模型构建的。