Java RMI - 简介



RMI 代表 **远程方法调用** (Remote Method Invocation)。它是一种机制,允许驻留在一个系统 (JVM) 中的对象访问/调用运行在另一个 JVM 上的对象。

RMI 用于构建分布式应用程序;它提供 Java 程序之间的远程通信。它位于 **java.rmi** 包中。

RMI 应用程序的架构

在 RMI 应用程序中,我们编写两个程序,一个 **服务器程序**(驻留在服务器上)和一个 **客户端程序**(驻留在客户端上)。

  • 在服务器程序内部,创建了一个远程对象,并使该对象的引用可供客户端使用(使用注册表)。

  • 客户端程序请求服务器上的远程对象,并尝试调用其方法。

下图显示了 RMI 应用程序的架构。

RMI Architecture

现在让我们讨论一下此架构的组件。

  • **传输层** - 此层连接客户端和服务器。它管理现有连接,并建立新的连接。

  • **存根** - 存根是客户端远程对象的表示(代理)。它驻留在客户端系统中;它充当客户端程序的网关。

  • **骨架** - 这是驻留在服务器端的对象。**存根**与这个骨架通信,将请求传递给远程对象。

  • **RRL(远程引用层)** - 它是一个管理客户端对远程对象引用的层。

RMI 应用程序的工作原理

以下几点总结了 RMI 应用程序的工作原理:

  • 当客户端对远程对象进行调用时,存根会接收该调用,并最终将此请求传递给 RRL。

  • 当客户端 RRL 接收请求时,它会调用对象 **remoteRef** 的名为 **invoke()** 的方法。它将请求传递给服务器端的 RRL。

  • 服务器端的 RRL 将请求传递给 Skeleton(服务器上的代理),Skeleton 最终调用服务器上的所需对象。

  • 结果被一路回传给客户端。

编组和反编组

每当客户端调用远程对象上接受参数的方法时,参数都会被打包成消息,然后通过网络发送。这些参数可以是基本类型或对象。对于基本类型,参数会被组合在一起,并附加一个标题。如果参数是对象,则会对其进行序列化。此过程称为 **编组**。

在服务器端,打包的参数会被解包,然后调用所需的方法。此过程称为 **反编组**。

RMI 注册表

RMI 注册表是一个命名空间,所有服务器对象都放置在此命名空间中。服务器每次创建对象时,都会使用 **bind()** 或 **reBind()** 方法将此对象注册到 RMI 注册表中。这些是使用称为 **绑定名称** 的唯一名称进行注册的。

要调用远程对象,客户端需要该对象的引用。此时,客户端使用其绑定名称(使用 **lookup()** 方法)从注册表中获取对象。

下图说明了整个过程:

Registry

RMI 的目标

以下是 RMI 的目标:

  • 最大程度地降低应用程序的复杂性。
  • 保持类型安全。
  • 分布式垃圾回收。
  • 最大程度地减少使用本地对象和远程对象之间的差异。
广告