服务器间通信:深入RMI的实现原理与技巧 (服务器间通信 rmi)

RMI(Remote Method Invocation)是Java远程方法调用的一种标准,可以实现Java对象在分布式系统中的远程调用。RMI是一种在分布式系统中提供远程对象访问和调用的机制,它使开发人员可以开发类似于本地对象的远程对象,并执行与本地对象相同的操作。

RMI的实现原理

RMI是在Java Remote Objects的基础上发展而来的。Java Remote Objects是把Java对象封装到网络上的一种技术,使得Java对象可以跨网络进行传输和调用。而RMI是在Java Remote Objects的基础之上扩展的,它增加了一些功能,使得Java对象可以像本地对象一样进行调用。

RMI主要依赖于Java的远程对象机制来实现远程方法调用。Java远程对象机制主要包括两个部分,即Java远程接口和Java远程对象。Java远程接口定义了远程对象所支持的方法,而Java远程对象实现了远程接口,并提供了远程对象的实例。

RMI的工作原理

RMI的工作过程可以分为以下三个步骤:

1.创建RMI Server

在RMI Server中注册需要暴露给客户端调用的远程对象,之后通过Naming类的bind()方法把注册的对象绑定到一个特定类名的URL上,等待客户端连接。

2.创建RMI Client

在客户端中,通过Naming类的lookup()方法查找绑定到指定URL的远程对象。得到远程对象之后就可以像调用本地对象一样调用远程方法。

3.远程方法调用

通过客户端调用远程对象的方法来实现方法的远程调用。客户端通过调用远程方法,就相当于向远程对象发起一次请求。这个请求会随着Java序列化机制将请求的参数打包成一个网络数据包发送到远端的RMI Server上。RMI Server接受到请求后,会根据请求携带的信息,找到相应的远程对象,并调用其对应的方法。方法执行后,返回值也通过Java序列化机制打包成网络数据包,发送回客户端,完成远程调用。

RMI的实现技巧

1.使用远程接口

在定义远程对象时,则应该将远程对象所支持的方法定义在一个独立的Java远程接口中。通过远程接口,可以让开发人员很容易地实现一些面向接口编程的技巧。

2.使用动态代理

RMI中给予了动态代理完成客户端与远程对象之间的信息交流。动态代理主要是用来生成某个接口的实现类的,然后将生成的实现类绑定到stub对象上。最后将stub对象绑定到Naming上,以便客户端可以通过Naming获取到远程对象的引用。

3.使用线程池

在实现RMI服务端时,为了提高服务端的性能和吞吐量,可以使用线程池来处理客户端请求。线程池可以有效地减少线程的创建和销毁,同时也能够提高线程的复用效率,从而提高服务端的性能。

通过本篇文章的介绍,我们可以了解到RMI的实现原理和技巧,将有助于我们在进行分布式系统开发时更好地利用RMI技术。同时,我们也可以结合其他的分布式系统技术,如CORBA、WebService、Socket等技术,来实现更加复杂的远程调用功能。

相关问题拓展阅读:

RMI 如何实现同步数据传递

RMI,远程方法调用(Remote Method Invocation)是Enterprise JavaBeans的支柱,是建立分布式Java应用程序的方便途径。RMI是非常容易使用的,但是它非常的漏拦竖强大。

RMI的基础是接口,RMI构架基于一个重要的原理:定义接口和定义接口的具体实现是分开的。下面我们通过具体的例子,建立一个简单的远程计算服务和使用它的客户程序

一个正常工作的RMI系统由下面几个部分组成:

● 远程服务的接口定义

● 远程服务接口的具体实现

● 桩(Stub)和框架(Skeleton)文件

● 一个运行远程服务的服务器

● 一个RMI命名服务,它允许客户端去发现这个远程服务

● 类文件的提供者(一个HTTP或者FTP服务衡枝器)

● 一个需要这个远程服务的客户端程序

下面我们一步一步建立一个简单的RMI系统。首先在你的机器里建立一个新的文件夹,以便放置我们创建的文件,为了简单起见,我们只使用一个文件夹存放客户端和服务端代码,并且在同一个目录下运行服务端和客户端。

如果所有的RMI文件都已经设计好了,那么你需要下面的几个步骤去生成你的系统:

1、 编写并且编译接口的Java代码

2、 编写并且编译接口实现的Java代码

3、 从接口实现类中生成桩(Stub)和框架(Skeleton)类文件

4、 编写远程服务的主运行程序

5、 编写RMI的客户端程序

6、 安装并且运行RMI系统

1、 接口

之一步就是建立和编译服务接口的Java代码。这个接口定义了所有的提供远程服务的功能,下面是源程序:

//Calculator.java

//define the interface

import java.rmi.Remote;

public interface Calculator extends Remote

{

public long add(long a, long b)

throws java.rmi.RemoteException;

public long sub(long a, long b)

throws java.rmi.RemoteException;

public long mul(long a, long b)

throws java.rmi.RemoteException;

public long div(long a, long b)

throws java.rmi.RemoteException;

}

注意,这个接口继承自Remote,每一个定义的方法都必须抛出返大一个RemoteException异常对象。

建立这个文件,把它存放在刚才的目录下,并且编译。

>javac Calculator.java

2、 接口的具体实现

下一步,我们就要写远程服务的具体实现,这是一个CalculatorImpl类文件:

//CalculatorImpl.java

//Implementation

import java.rmi.server.UnicastRemoteObject

public class CalculatorImpl extends UnicastRemoteObject implements Calculator

{

// 这个实现必须有一个显式的构造函数,并且要抛出一个RemoteException异常

public CalculatorImpl()

throws java.rmi.RemoteException {

super();

}

public long add(long a, long b)

throws java.rmi.RemoteException {

return a + b;

}

public long sub(long a, long b)

throws java.rmi.RemoteException {

return a – b;

}

public long mul(long a, long b)

throws java.rmi.RemoteException {

return a * b;

}

public long div(long a, long b)

throws java.rmi.RemoteException {

return a / b;

}

}

同样的,把这个文件保存在你的目录里然后编译他。

这个实现类使用了UnicastRemoteObject去联接RMI系统。在我们的例子中,我们是直接的从UnicastRemoteObject这个类上继承的,事实上并不一定要这样做,如果一个类不是从UnicastRmeoteObject上继承,那必须使用它的exportObject()方法去联接到RMI。

如果一个类继承自UnicastRemoteObject,那么它必须提供一个构造函数并且声明抛出一个RemoteException对象。当这个构造函数调用了super(),它久激活UnicastRemoteObject中的代码完成RMI的连接和远程对象的初始化。

3、 桩(Stubs)和框架(Skeletons)

下一步就是要使用RMI编译器rmic来生成桩和框架文件,这个编译运行在远程服务实现类文件上。

>rmic CalculatorImpl

在你的目录下运行上面的命令,成功执行完上面的命令你可以发现一个Calculator_stub.class文件,如果你是使用的Java2SDK,那么你还可以发现Calculator_Skel.class文件。

4、 主机服务器

远程RMI服务必须是在一个服务器中运行的。CalculatorServer类是一个非常简单的服务器。

//CalculatorServer.java

import java.rmi.Naming;

public class CalculatorServer {

public CalculatorServer() {

try {

Calculator c = new CalculatorImpl();

Naming.rebind(” c);

} catch (Exception e) {

System.out.println(“Trouble: ” + e);

}

}

public static void main(String args) {

new CalculatorServer();

}

}

建立这个服务器程序,然后保存到你的目录下,并且编译它。

5、 客户端

客户端源代码如下:

//CalculatorClient.java

import java.rmi.Naming;

import java.rmi.RemoteException;

import java.net.MalformedURLException;

import java.rmi.NotBoundException;

public class CalculatorClient {

public static void main(String args) {

try {

Calculator c = (Calculator)

Naming.lookup(

/CalculatorService”);

System.out.println( c.sub(4, 3) );

System.out.println( c.add(4, 5) );

System.out.println( c.mul(3, 6) );

System.out.println( c.div(9, 3) );

}

catch (MalformedURLException murle) {

System.out.println();

System.out.println(

“MalformedURLException”);

System.out.println(murle);

}

catch (RemoteException re) {

System.out.println();

System.out.println(

“RemoteException”);

System.out.println(re);

}

catch (NotBoundException nbe) {

System.out.println();

System.out.println(

“NotBoundException”);

System.out.println(nbe);

}

catch (

java.lang.ArithmeticException

ae) {

System.out.println();

System.out.println(

“java.lang.ArithmeticException”);

System.out.println(ae);

}

}

}

保存这个客户端程序到你的目录下(注意这个目录是一开始建立那个,所有的我们的文件都在那个目录下),并且编译他。

6、 运行RMI系统

现在我们建立了所有运行这个简单RMI系统所需的文件,现在我们终于可以运行这个RMI系统啦!来享受吧。

我们是在命令控制台下运行这个系统的,你必须开启三个控制台窗口,一个运行服务器,一个运行客户端,还有一个运行RMIRegistry。

首先运行注册程序RMIRegistry,你必须在包含你刚写的类的那么目录下运行这个注册程序。

>rmiregistry

好,这个命令成功的话,注册程序已经开始运行了,不要管他,现在切换到另外一个控制台,在第二个控制台里,我们运行服务器CalculatorService,因为RMI的安全机制将在服务端发生作用,所以你必须增加一条安全策略。以下是对应安全策略的例子

grant {

permission java.security.AllPermission “”, “”;

};

注意:这是一条最简单的安全策略,它允许任何人做任何事,对于你的更加关键性的应用,你必须指定更加详细安全策略。

现在为了运行服务端,你需要除客户类(CalculatorClient.class)之外的所有的类文件。确认安全策略在policy.txt文件之后,使用如下命令来运行服务器。

> java -Djava.security.policy=policy.txt CalculatorServer

这个服务器就开始工作了,把接口的实现加载到内存等待客户端的联接。好现在切换到第三个控制台,启动我们的客户端。

为了在其他的机器运行客户端程序你需要一个远程接口(Calculator.class) 和一个stub(CalculatorImpl_Stub.class)。 使用如下命令运行客户端

prompt> java -Djava.security.policy=policy.txt CalculatorClient

如果所有的这些都成功运行,你应该看到下面的输出:

1

9

18

3

如果你看到了上面的输出,恭喜你,你成功了,你已经成功的创建了一个RMI系统,并且使他正确工作了。即使你运行在同一个计算机上,RMI还是使用了你的网络堆栈和TCP/IP去进行通讯,并且是运行在三个不同的Java虚拟机上。这已经是一个完整的RMI系统。

webservices,corba,jms,rpc,rmi的区别和概述

1、web service体系结构

首先客户端从服务器的到WebService的WSDL,同时在客户端声称一个代理类(Proxy Class)

这个代理类负责与WebService服务器进行Request 和Response

当一个数据(XML格式的)被封装成SOAP格式的数据流发送到服务器端或尺的时候,就会生成一个进程对象并且把接收到这个Request的SOAP包进行解析,然后对事物进行处理,处理结束以后再对这个计算结果进行SOAP包装,然后把这个包作为一个Response发送给客户端的代理类(Proxy Class),同样地,这个代理类也对这个SOAP包进行解析处理,继而进行后续操作。这就是WebService的一个运行过程。

Web Service大体上分为5个层次:

1. Http传输信道

2. XML的数据格式

3. SOAP封装格式

4. WSDL的描述方式

5. UDDI

2、RCP

客户机对服务器的RPC调用,其内部操作大致有如下十步:

1.调用客户端句柄;执行传送参数、

2.调用本地系统内核发送网络消息、

3.消息传送到远程主机

4.服务器句柄得到消息并取得参数、

5.执行远程过程、

6.执行的过程将结果返回服务器句柄

7.服务器句柄返回结果,调用远程系统内核、

8.消息传回本地主机、

9.客户句柄由内核接收消息、

10.客户接收句柄返回的数据

3、webservices/corba/jms/rpc/rmi区别

web service提供的服务是基于web容器的,底层使用http协议,类似一个远程的服务提供者,比如天气预报服务,对各地客户端提供天气预报,是一种请求应答的机制,是跨系统跨平台的。webservice服务端是运行在web服务器上的,不过也可以使用Remoting命名空间,创建c/s式的服务,比如CORBA就是c/s的方式提供服务

3.1RPC与Web Service

1、RPC可以灵薯团纯活的定义其所基于的协议,如果定义为HTTP,则与Web Service就没有什么区别了,一般都喜欢定义为TCP,这样比Web Service稍为高效一些

2、RPC不是标准,而Web Service是标准;

3、RPC一般需要通过一个WinForm或是Windows服务进行启动,而Web Service则需要web服务进行启动

我建议还是采用Web Service好些,对于开发来说更容易控制RPC一般用在C/S的系统中,Web Service是用在B/S系统中

后者还是各语言的通用接口

3.2RPC与RMI

远程对象方法调用并不是新概念,远程过程调用 (RPC) 已经使用很多年了。远程过程调用被设计为在应用程序间通信的平台中立的方式,它不理会操作系统之间以及语言之间的差异。即 RPC 支持多种语言,而 RMI 只支持 Java 写的应用程序。 另外 RMI 调用远程对象方法,允许方法返回 Java 对象以及基本数据类型。而 RPC 不支持对象的概念,传送到 RPC 服务的消息由外部数咐数据表示 (External Data Representation, XDR) 语言表示,这种语言抽象了字节序类和数据类型结构之间的差异。只有由 XDR 定义的数据类型才能被传递, RPC 不允许传递对象。可以说 RMI 是面向对象方式的 Java RPC 。

3.3JMS 与RMI

Java 消息服务 ( Java Messaging Service, JMS ) 是一种允许应用程序创建、发送、接受和读取消息的Java API 。 JMS 与 RMI 的区别在于,采用 JMS 服务,对象是在物理上被异步从网络的某个 JVM 上直接移动到另一个 JVM 上(支持消息通知?如xmpp协议)JMS 消息的两种模式(Point-to-Point(P2P)和Publish/Subscribe(Pub/Sub) )

而 RMI 对象是绑定在本地 JVM 中,只有函数参数和返回值是通过网络传送的(是请求应答机制)。

3.4CORBA、RMI、webservices

在使用CORBA进行系统通信架构,CORBA使用统一的IDL接口而webservices使用wsdl,一个是c/s命名服务,一个是基于web提供的服务,CORBA还有事件服务,是在命名服务上的一个服务,可以实现消息的通知,而webservices是请求应答模式的。CORBA年数已久比较成熟,有很多大公司支持,后来慢慢走下坡路,使用corba是一个很繁琐的事情,对于后来的系统建议使用webservices进行开发,现在eclipse对webservices服务端快速开发提供了很好的支持,并且有Axis,axis2,Xfire以及cxf的支持,他们的对比请参阅

企业SOA架构思想,对企业ESB系统很好的接入

CORBA 是 90 年代初有 OMG 组织提出的一个分布式互操作标准,跨平台语言的Java有JACORB支持。而 RMI 直接把分布式对象模型嵌入到 Java 语言的内部,使得 Java程序员可以自然的编写分布式程序,不必离开 Java 环境,或者涉及 CORBA IDL 以及 Java 到 CORBA 的类型转换。然而 RMI 不遵守 CORBA 标准,基本上是Java-to-Java 技术,难以实现与其他语言编写的对象之间的互操作

RMI 和 CORBA 常被视为相互竞争的技术,因为两者都提供对远程分布式对象的透明访问。但这两种技术实际上是相互补充的,一者的长处正好可以弥补另一者的短处。 RMI 和 CORBA 的结合产生了 RMI-IIOP, RMI-IIOP 是企业服务器端 Java 开发的基础。

1997 年, IBM 和 Sun Microsystems 启动了一项旨在促进 Java 作为企业开发技术的发展的合作计划。两家公司特别着力于如何将 Java 用作服务器端语言,生成可以结合进现有体系结构的企业级代码。所需要的就是一种远程传输技术,它兼有 Java 的 RMI

( Remote Method Invocation ,远程方法调用)较少的资源占用量和更成熟的 CORBA ( Common Object Request Broker Architecture ,公共对象请求代理体系结构)技术的健壮性。出于这一需要, RMI-IIOP问世了,它帮助将 Java 语言推向了目前服务器端企业开发的主流语言的领先地位 。

Java远程方法调用()

概述Java Remote Method Invocation ( RMI Java远程方法调用)允许您使用Java编写分布式对象 本文将介绍RMI的优点以及如何将其连接到现有的和原有的系统中 以及与用Java 编写的组件的连接RMI为采用Java对象的分布式计算提供了简单而直接的途径 这些对象可以是新的Java对象 也可以是围绕现有API的简单的Java包装程序 Java体现了 编写一次就能在任何地方运行的模式 而RMI可将Java模式进行扩展 使之可在任何地方运行因为RMI是以Java为核心的 所以 它将Java的安全性和可移植性等强大功能带给了分布式计算 您可将代理和梢?务逻辑等属性移动到网络中最合适的地方 如果您要扩展Java在系统中的使用 RMI将使您充分利用其强大功能RMI可利用标准Java本机方法接口JNI与现有的和原有的系统相连接 RMI还可利用标准JDBC包与现有的关系数据库连接 RMI/JNI和RMI/JDBC相结合 可帮助您利用RMI与目前使用非Java语言的现有服务器进行通信 而且在您需要时可扩展Java在这些服务器上的使用 RMI可帮助您在扩展使用时充分利用Java的强大功能     优点从最基本的角度看 RMI是Java的远程过程调用(RPC)机制 与传统的RPC系统相比 RMI具有若干优点 因为它是Java面向对象方法的一部分 传统的RPC系统采用中性语言 所以是最普通的系统 它们不能提供所有可能的目标平台所具有的功能RMI以Java为核心 可与采用本机方法与现有系统相连接 这就是说 RMI可采用自然 直接和功能全面的方式为您提供分布式计算技术 而这种技术可帮助您以不断递增和无缝的方式为整个系统添加Java功能     RMI的主要优点如下      面向对象 RMI可将完整的对象作为参数和返回值进行传递 而不仅仅是预定义的数据类型 也就是说 您可以将类似Java哈希表这样的复杂类型作为一个参数进行传递 而在目前的RPC系统中 您只能依靠客户机将此类对象分蚂塌解成基本数据类型 然后传递这些数据类型 最后在服务器端重新创建哈希表 RMI则不需额外的客户程序代码(将对象分解成基本数据类型) 直接跨网传递对象    可移动属性 RMI可将属性(类实现程序)从客户机移动到服务器 或者从服务器移到客户机 例如 您可以定义一个检查雇员开支报告的接口 以便察看雇员是否遵守了公司芹亮目前实行的政策 在开支报告创建后 客户机就会从服务器端获得实现该接口的对象 如果政策发生变化 服务器端就会开始返回使用了新政策的该接口的另一个实现程序 您不必在用户系统上安装任何新的软件就能在客户端检查限制条件 从而向用户提供烁?快的反馈 并降低服务器的工作量 这样就能具备更大的灵活性 因为政策改变时只需要您编写一个新的Java类 并将其在闷首圆服务器主机上安装一次即可    设计方式 对象传递功能使您可以在分布式计算中充分利用面向对象技术的强大功能 如二层和三层结构系统 如果您能够传递属性 那么您就可以在您的解决方案中使用面向对象的设计方式 所有面向对象的设计方式无不依靠不同的属性来发挥功能 如果不能传递完整的对象 包括实现和类型 就会失去设计方式上所提供的优点    安  全 RMI使用Java内置的安全机制保证下载执行程序时用户系统的安全 RMI使用专门为保护系统免遭恶意小应用程序侵害而设计的安全管理程序 可保护您的系统和网络免遭潜在的恶意下载程序的破坏 在情况严重时 服务器可拒绝下载任何执行程序   便于编写和使用 RMI使得Java远程服务程序和访问这些服务程序的Java客户程序的编写工作变得轻松 简单 远程接口实际上就是Java接口 服务程序大约用三行指令宣布本身是服务程序 其它方面则与任何其它Java对象类似 这种简单方法便于快速编写完整的分布式对象系统的服务程序 并快速地制做软件的原型和早期版本 以便于进行测试和评估 因为RMI程序编写简单 所以维护也简单    可连接现有/原有的系统 RMI可通过Java的本机方法接口JNI与现有系统进行进行交互 利用RMI和JNI 您就能用Java语言编写客户端程序 还能使用现有的服务器端程序 在使用RMI/JNI与现有服务器连接时 您可以有选择地用Java重新编写服务程序的任何部分 并使新的程序充分发挥Java的功能 类似地 RMI可利用JDBC 在不修改使用数据库的现有非Java源代码的前提下与现有关系数据库进行交互    编写一次 到处运行 RMI是Java 编写一次 到处运行 方法的一部分 任何基于RMI的系统均可 %地移植到任何Java虚拟机上 RMI/JDBC系统也不例外 如果使用RMI/JNI与现有系统进行交互工作 则采用JNI编写的代码可与任何Java虚拟机进行编译 运行    分布式垃圾收集 RMI采用其分布式垃圾收集功能收集不再被网络中任何客户程序所引用的远程服务对象 与Java 虚拟机内部的垃圾收集类似 分布式垃圾收集功能允许用户根据自己的需要定义服务器对象 并且明确这些对象在不再被客户机引用时会被删除    并行计算 RMI采用多线程处理方法 可使您的服务器利用这些Java线程更好地并行处理客户端的请求 Java分布式计算解决方案 RMI从JDK 开始就是Java平台的核心部分 因此 它存在于任何一台 Java虚拟机中 所有RMI系统均采用相同的公开协议 所以 所有Java 系统均可直接相互对话 而不必事先对协议进行转换    lishixinzhi/Article/program/Java/hx/202311/26469

服务器间通信 rmi的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于服务器间通信 rmi,服务器间通信:深入RMI的实现原理与技巧,RMI 如何实现同步数据传递,webservices,corba,jms,rpc,rmi的区别和概述,Java远程方法调用()的信息别忘了在本站进行查找喔。


数据运维技术 » 服务器间通信:深入RMI的实现原理与技巧 (服务器间通信 rmi)