用RMI开拓基于Java的企业漫衍式应用
副标题#e#
摘 要 由于Java具有跨平台、代码可移植性、安详高效等遍及而强大的成果,因而在开拓网络漫衍式应用的时候,可以用它自身的机制实现漫衍式计较,一种基于Java的长途要领挪用(RMI)为我们开拓企业漫衍式应用提供了行之有效的办理方案。
要害词 Java RMI 企业漫衍式应用
概述
跟着电力企业信息化建树的不绝深入和成长,企业内部和企业与企业之间对信息、对数据的互换量大大增加,这些信息与数据越来越需要在差异的计较机网络间传送和交换。同时,由于各单元、各部分之间的现存的计较机网络硬件设备与操纵系统千差万别,应用程度也东倒西歪,因此,开拓出跨平台、可移植、高效安详的网络漫衍式应用来处事于电力企业,就显得尤为重要。
在当今的编程术语里,漫衍式计较已经成为很常见的词,它将企业的业务数据和措施漫衍在网络的差异物理位置上,通过更换网络上多台计较机的处理惩罚本领,发挥长途挪用数据的成果。
长途要领挪用(Remote Method Invocation ,RMI),可以在差异的Java虚拟机(JVM)之间实现工具与工具的通信。JVM可以位于沟通或差异计较机上,在多个JVM中,一个JVM可以挪用存储在其它JVM的工具的要领。
本文主要先容RMI的特点,阐明应用RMI举办企业漫衍式计较的道理,以及操作RMI实现基于Java的企业漫衍式应用的详细步调。
长途要领挪用(RMI)的特点
1、TCP编程的缺点
由于Java编程语言设计之初就是面向工具和支持网络的,因此,基于工具的RMI机制已经内置在Java平台中。
我们常常会在网络开拓中利用TCP/IP编程,这样,自然而然地就会涉及到Socket(套接字)编程。可是,利用Socket编程需要大量反复编码,在巨大漫衍式操纵时显得很是贫苦,并且易于堕落。因此,如何快速、高效、安详、可扩展地举办网络漫衍式计较,是开拓者们一贯追求和建议的主题。直到RMI的呈现,这种繁杂、低效的开拓环境才有很大更改。
2、RMI编程的特点
当我们操作工具序列化在网络上分派工具时,RMI提供了非Java平台无法对抗的奇特而强大的漫衍式计较模子,RMI主要有以下特点:
客户机可以向当处所法一样挪用长途处事器上的要领;
可以按照接口指定客户机/处事器编程合约;
可以从处事器工具缺省二进制类文件,自动生成更换/反更换代码;
将Java编程模子扩展到呆板界线(和Java虚拟机(JVM)界线之外),不需要任何非凡语法;
还可以和一个长途要领挪用中的数据同时传输行为(代码)。
尽量RMI不是独一的企业级长途工具会见方案,但它却是最容易实现的。
3、RMI与CORBA
作为漫衍式应用措施框架的类型,COBRA首当其冲,它是由工具打点组织(OMG)开拓的。与CORBA差异的是,CORBA可以或许操作差异编程语言(譬喻C/C++、Basic等)开拓实现漫衍式应用,而RMI是一种纯Java办理方案。在RMI中,措施的所有部门都由Java语言编写,这样,开拓出来的措施完全切合Java类型,便于实现跨平台会见、扩展和移植。凭据笔者地址西北电力建树团体公司的环境看,处事器操纵系统主要有Linux和Windows2000 Server,别离存在于公司和部分傍边,它们是差异的系统平台;同时,公司部属各个工程项目部又间隔很远,近的几十公里,远则到达上千公里甚至位于海外,因此跨平台和长途会见这两大成果在开拓企业应用系统时就必需思量,而RMI恰恰可以或许用它的自身特点来满意编程需要。
#p#副标题#e#
RMI根基体系布局简介
RMI通过TCP/IP在内部利用Socket,象其名称体现的那样,它可以或许辅佐我们查找并执行长途工具的要领。RMI的目标是让位于差异JVM中的工具,在外观及行为上都像是当地的工具。
凡是,我们把挪用这种长途工具的JVM,称为客户机;而把包罗这种长途工具的JVM,称为处事器。
尽量对一个长途工具的引用和得到对当地工具的引用有所差异,但我们可以把长途工具像当地工具一样利用。应用措施并不知道一个工具是长途的照旧当地的。实际上,长途工具上被挪用的要领与当地工具上挪用的要领,具有沟通的语法布局。
作为RMI的底层(会包括巨大的Socket操纵),它会自动截获要领挪用,找到长途工具,然后处理惩罚长途请求。笔者认为,RMI设计的重要之处,就在于不单在设计上实现了长途会见成果,并且实现了设计的透明性。
RMI的根基体系布局,归纳综合起来说,由三个抽象层构成:
1、存根/框架层(Stubs/Skeletons Layer)
RMI为我们引入了两种非凡范例的工具,称为存根(Stub)和框架(Skeleton),它们构成了RMI的第一层。
#p#分页标题#e#
在长途通信的时候,要操作TCP/IP协议,做许多底层数据的打包传输。运用Java技能,我们先要把数据可能工具转换成字节约(byte stream),便于网络传输,这个进程叫搜集(marshaling);当收到长途传来的字节约后,我们要把流信息转换成工具可能数据,这个进程叫解读(unmarshaling),它与搜集恰好相反。
Stub和Skeleton层位于实际应用措施之下,成立在Proxy(署理)设计方案之上。Stub类的浸染是长途处事器实现的署理的脚色,Stub是客户方工具;Skeleton类用于辅佐工具通过RMI链接与Stub通信,它从链路中读取要领挪用的参数,向长途处事实现工具举办挪用,接管返回值,然后再把返回值写回到Stub。
2、长途引用层(Remote Reference Layer)
长途引用层界说和支持着RMI毗连的挪用语义(semantics)。
RMI举办长途会见要用到JRMP(Java Remote Method Protocol,即Java长途要领协议),这一层提供专用于JRMP的RemoteRef工具,它位于java.rmi.server包内,代表着长途工具的一个句柄。RemoteRef利用长途引用来执行长途工具的一个长途要领挪用。
3、传输层(Transport Layer)
传输层在JVM之间成立基于流的网络毗连,而且认真配置和打点这些毗连。这时候,RMI利用一种线级(wire-level)协议举办基于TCP/IP的毗连,该协议就是Java长途要领协议(JRMP,即Java Remote Method Protocol)。
在JDK版本1.2开始,JRMP不再需要Skeleton,而是利用reflection来成立与长途处事的毗连。为了生成Stub,我们须用rmic。
当前的RMI实现中,传输层成立在TCP/IP基本上,设计用于在客户和处事器之间成立一条毗连(纵然联网有障碍)。
开拓的根基步调
我们利用RMI编写Client/Server模式(客户/处事器)应用措施,包罗6个根基步调:
1) 界说长途接口
2) 实现长途接口
3) 筹备长途挪用的处事器工具
4) 生成残根Stub(客户署理)和框架Skeleton(处事器实体)
5) 用rmiregistry找到长途工具
6) 运行测试RMI漫衍式应用
开拓企业信息宣布系统实例
在开拓RMI举办漫衍式会见之前,需要将各项成果模块化,即把实际应用抽象成切合Java类型的类和接口模子,使这些类和接口之间相互协作,能实现各自独立的成果,最后,可以把它们组合成统一的网络漫衍式系统。
此刻,我们就以开拓公司信息宣布系统为例,把主模块(主要的类文件)的名称暂定为InfoDistributeService(信息宣布处事),为了保持应用开拓的数据一致性和清晰度,接下来涉及的其它模块定名也将以这个模块定名为基准。
1、界说长途接口
Java RMI运行情况要求任何可以长途挪用的要领必需放在长途接口中。
该长途接口用来扩展java.rmi.Remote接口,在Java API中,可以发明它没有任何要领,只是个符号性接口,这样,可以让Java运行情况(JRE)认识每个接口的非凡属性,以便可以或许长途会见。
因此,凭据信息宣布处事的定名(InfoDistributeService),首先须将InfoDistributeRemote界说为长途接口,同时仅放入一个供测试的要领 getRemoteInfo()来实现编码,将所有模块至于新建的enterprise.distribute包中,代码如下:
// -----------InfoDistributeRemote.java-------------------
package enterprise. distribute;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface InfoDistributeRemote extends Remote{
public String getRemoteInfo() throws RemoteException;
}
2、实现长途接口
这是一个实现长途工具的类。假如实现了长途接口,就可以或许包围(override)该工具中的所有要领,因此,长途工具的实现类将真正包括我们但愿导出的要领的代码。
在长途信息宣布系统中,我们至少实现一个长途接口的工具,它就是长途可会见的工具。这里,InfoDistributeService类可觉得我们生生长途可会见工具的实例:
// -----------InfoDistributeService.java------------------
package enterprise. distribute;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class InfoDistributeService
extends UnicastRemoteObject implements InfoDistributeRemote{
public InfoDistributeService() throws RemoteException{
super();
}
// The return value of the method only for testing...
public String getRemoteInfo(){
return "Hello! I am a remote object.";
}
}
InfoDistributeService类实现长途接口InfoDistributeRemote,并担任java.rmi.server.UnicastRemoteObject。由于切合InfoDistributeRemote接口,因此该类除结构要领之外,还应有getRemoteInfo()要领,并且必需将该要领实现。
#p#分页标题#e#
同时我们留意到,getRemoteInfo()要领抛出了java.rmi.RemoteException异常。由于长途要领挪用进程中,要举办许多的初级网络操纵,因此网络错误大概在挪用进程中随时产生,这样,长途接口中的每个要领(尽量这里只有一个getRemoteInfo()要领)都必需抛出RemoteException异常,并且,java.rmi.RemoteException都要在代码中显式处理惩罚,即将所有RMI勾当涉及的代码都要放在try-catch块中。
3、筹备供长途挪用的处事器工具
这是一个作为处事器利用的类,它是相对付要会见长途要领的客户端而言的。它存储着绑定的字符串和工具。
将长途工具配置成接管长途挪用就像启动了侦听ServerSocket工具的socket处事器。事实上在利用RMI时,TCP/IP协议的传输方法,在幕后产生了许多底层网络操纵,可是而今,用户不需要知道这些细节,只需要慢慢导出长途工具:
在Java开拓东西的较新版本JDK 1.4中,可以选择java.rmi.UnicastRemoteObject可能java.rmi.Activation.Activatable。个中,更多用到的是UnicastRemoteObject,因为它顾名思义,就是在客户机与处事器工具实例之间成立一对一毗连。
4、生成Stub和Skeleton
由RMI生成的更换与反更换的长途更换代码也和Java的其它代码一样,都包括在后缀是.class的文件中。
运用RMI之后,在客户机上生成的更换参数和反更换返回值的代码称为残根(Stub),处事器上生成的反更换参数和举办实际要领挪用更换返回值的代码称为框架(Skeleton)。
可以利用RMI自带的呼吁行东西rmic(即RMI Compiler),先扫描长途工具的.class文件,随之生成残根与框架代码。东西rmic的道理如图1。
5、长途客户端:这是一个辅佐我们会见长途要领提供辅佐的类,它也是最终用户。我们将利用查找和挪用长途要领的要领在该类中挪用长途要领。
典范的rmic挪用如下(在当前目次): 我们有了长途接口和实现,就可以用rmic对类举办编译,生成Stub和Skeleton,在呼吁行窗口中利用以下代码行:
// compile all java source files
javac enterprise\distribute\*.java
// make stub and skeleton code
rmic enterprise.distribute.InfoDistributeService
运行完毕后,在当前目次生成下列文件(即更换代码):
InfoDistributeService_Stub.class
InfoDistributeService_Skel.class
5、用rmiregistry找到长途工具
导出处事器方的工具之后,就可以长途会见,但客户机还要设法与这些长途工具取得接洽。
由于漫衍式应用措施大概涉及很多差异呆板,因此通信的所有呆板对之间需要成立初始毗连,换句话说,就是要设法找到初始长途工具,这项事情通过rmiregistry呼吁执行。
JDK开拓东西提供了实用措施RMI Registry,用来维护文本名和长途工具之间的映射,可以举办长途会见。
在客户机方,RMI注册表可以通过同一java.rmi.Naming类的lookup()静态要领用措施会见。譬喻,长途主机为iServer,长途工具实例为InfoDistributeService实例,长途端标语为5678,则客户机假如查找长途主机iServer中的长途InfoDistributeService实例,那么引用实例时须利用长途接口InfoDistributeRemote,代码如下:
InfoDistributeRemote iServer=( InfoDistributeRemote)Naming.lookup("rmi://iServer:5678/InfoDistributeService");
在处事器方,导出的长途工具可以通过java.rmi.Naming类在当地注册rmiregistry的运行实例。譬喻,用rebind()要领将iService中的InfoDistributeService的实例与名称InfoDistributeService相关联。
InfoDistributeService iService=new InfoDistributeService();
Naming.rebind("/ InfoDistributeService",iService);
综上所述,InfoDistributeRemote是个Java接口,因此iServer实际上是实现InfoDistributeRemote接口的当地工具实例,它不在长途,而是长途InfoDistributeService的当地暗示。也就是说,它是由前述rmic东西自动生成的残根码InfoDistributeService_Stub.class的当地实例。图3显示了长途工具挪用的事情道理。
图2 长途工具挪用的事情道理
从图2可以看出,客户机实现通过iServer变量维护长途工具的挪用。事实上,iServer引用变量是实现InfoDistribute接口的工具的当地引用,该工具是InfoDistributeService残根实现。这个残根和处事器方的框架一起通过InfoDistributeRemote接口更换/反更换所有长途挪用。
当我们把InfoDistributeService当作是实现InfoDistributeRemote接口的当地实例的时候,残根代码只在幕后举办事情,而实现这一切则变得很是透明。
由上述道理,可以进一步设计完善客户机和处事器代码,进而编写出完整的应用措施。
6、运行测试RMI漫衍式应用
#p#分页标题#e#
在确认已经设计好必需的几大类模块后,我们开始按以下步调,运行并测试该信息宣布系统的根基成果(即仅仅实现长途接口中声明的getRemoteInfo()要领)。
在前面界说的包enterprise.distribute中,执行javac呼吁编译后缀为.java的源文件。
javac enterprise/distribute/*.java
接着,用RMIC东西生成残根与框架。
rmic enterprise.distribute.InfoDistributeService
编译之后,需要确定客户机与处事器刊行版本的内容。因此,需用jar呼吁,将客户机与处事器刊行版本包装成 .jar文件。 个中,包装处事器的文件呼吁如下:
jar cvf InfoDistributeService.jar
enterprise\distribute\InfoDistributeService.class
enterprise\distribute\InfoDistributeRemote.class
enterprise\distribute\InfoDistributeService_Stub.class
enterprise\distribute\InfoDistributeService_Skel.class
同样,包装客户机的雷同于以上呼吁。
运行RMI应用措施
完成了第一阶段的所有RMI试验,然后运行信息宣布应用措施。凭据Java类型,需要依次启动下列项目:
启动RMIRegistry
在代码目次顶用以下呼吁启动rmiregistry实例,使之在节制台开始运行。
start rmiregistry
启动处事器
直接启动处事器,生成InfoDistributeService长途工具的实例,并向注册表注册。
start java -classpath InfoDistributeService.jar
enterprise.distribute.InfoDistributeService
启动客户机
最后,用java -classpath RemoteClient.jar 呼吁启动客户机,然后通过rmiregistry找到长途信息宣布处事,再通过长途挪用获得所需要的长途信息。
结论
本文扼要叙述了Java RMI的特点,以及用RMI开拓企业漫衍式应用的主要步调。以长途信息宣布系统为例,简腹地说明白长途工具会见、长途要领挪用在信息宣布时的道理和实现进程。
为了开拓出更切合实际的企业漫衍式应用,RMI还可以团结工具序列化实现越发强大的成果,为我们开拓越发机动、高效的网络漫衍式应用系统提供利便。