RMI学习(一)

RMI 概念

远程方法调用( Remote Method Invocation, RMI )是一种基于 Java 的分布式编程模型。

一次远程方法调用( RMI )的过程为:客户端将请求翻译成某种中间传输格式,然后将请求发送给服务器。服务器端解析该请求,通过运算得到响应,再将响应格式化并传递给客户,然后客户端解析响应并将它呈现给用户。

RMI 遇到的问题有:提供服务的对象可能不在同一个虚拟机内,甚至可能不是 Java 语言实现的对象,所以上面提到的“将请求翻译成某种中间传输格式”就有其必要性。

解决的办法是,在客户端和服务器端都安装一个代理。这些代理负责解决参数的序列化和通信问题。通常我们把客户端的代理成为存根( Stub ),服务器端的代理称为骨架( Skeleton ;

存根的作用是将远程方法所需的参数打包成一组字节(与硬件无关,在 RMI 中,这个过程称为参数编组 parameter marshalling, 目的是将参数转化成合适在虚拟机之间进行传递的格式)。这些过程在 RMI 中都是全部都是自动的。

代理之间的通信通常方式除了 RMI 外,还有 CORBA SOAP ,这两种方式是全独立于语言的。 CORBA 使用 Internet Inter-ORB 协议( IIOP )来支持对象间的通信,和 CORBA 兼容的 RMI 称为 RMI-IIOP SOPA 则是 WEB 服务表述语言( WSDL ),以 XML 形式编写。

 

RMI 程序的设计

RMI 程序设计的两部分:客户端,服务器端。程序运行时,还要涉及到服务器对象的定位问题(因为服务程序可能分布在很多的不同的服务器上面,而分布式对象编程模型的一个目的是“从客户机的视角看,远程方法的调用就像调用本地方法一样”,怎么办呢。其实这些事情都是 stub 做好了。 );

RMI 程序运行的完整过程

服务器 :

1. 启动时,向 RMI 注册表进行名字注册。

客户端:

1. 客户端请求时,首先向 RMI 注册表查询方法所处的位置(方法所处的服务器);

2. 向特定的服务器获取所要的方法(服务器返回的是一个 Stub );

3. Stub 转化成相应的类型(一个自定义接口,继承自 Remote ,暴露了商业方法),然后远程调用相应的商业方法;

 

相应的 RMI 部署和运行的步骤

1. 启动 RMI 注册表,以便服务器向其注册服务;

2. 启动服务器端代码,并使其常驻内存,为客户端提供服务

3. 启动客户端,查询并调用服务器方法;

 

具体的代码分析为:

启动 RMI 注册表

方法为: start rmiregistry (Windows 中的方法,其中 rmiregistry 命令是在 JRE/BIN 文件夹下的一个可执行文件 )

 

服务器端:

1. 定义 Remote 接口的子接口,用于暴露商业方法( stub 会根据这个生成相应的东西)

2. 编写一个继承 1 中定义接口的服务器类,实现相应的商业方法;服务器类通常继承自 RemoteServer 类(抽象类),而 UnicastRemoteObject 类(继承自 RemoteServer )是实体类,提供了 RemoteServer 的缺省实现,我们通常继承自它。 UnicastRemoteObject 使服务器类具有服务器的功能(能够处理 TCP/IP 的一些事务)。除了继承 UnicastRemoteObjec 来让我们的服务器类具有服务器功能外,调用这个方法:         UnicastRemoteObject.exportObject(service, 0); 其中 service 是提供服务的类实例, 0 表明任意合适的端口都可以用来监听客户连接;)也能够使我们的服务器类具有服务器的功能。

4. 把商业方法注册到 RMI 注册表,代码如下:

ProductImpl p1 = new ProductImpl(…);

Context namingContext = new InitialContext();

namingContext.bind(“rmi:toaster”, p1);

上面的代码注册了 2 中创建的类的实例 p1 ,命名为 toaster ,我们可以通过如下“ rmi://yourserver.com/toaster ”(“ yourserver.com ”为存放 toaster 对象的服务器的 url ,本地测试时为 localhost )来访问这个对象;

5. 生成 Stub ,从 JDK 5.0 开始,存根类都可以自动生成。在此之前,我们要通过下面的代码来创建 Stub

                                               Rmic –v1.2 ServerImpl

ServerImpl 就是 2 中创建的程序。在运行 rmic 之前,先用 javac 编译源代码。

 

客户端

                   Product p = (Product) namingContext.lookup(“rmi://yourserver.com/toaster”);

RMI 的安全问题

因为 RMI 是要经过网络通信的,所以安全问题就显得十分必要。我们在使用 RMI 的客户端进行通信时,应该安全一个安全管理器( RMISecurityManager ),用以控制动态加载 Stub 的行为。代码如下:

           System.setSecurityManager(new RMISecurityManager());

另外在安装上面的安全管理器之前,我们要设置一个安全文件:“

           System.setProperty(“java.security.policy”, “client.policy”);

安全文件 client.policy 的内容如下:

           grant{

                             permission java.net.SocketPermission “*:1024-65535”, “connect”;

           };

安全文件的意思为:它允许应用程序建立任何网络连接,只要端口号不小于 1024 即可。

 

将要深入学习的知识

RMI-IIOP JNDI,  java 安全策略

 

参考文献

java 核心技术》第 7 第五章 分布式对象

RMI : http://java.sun.com/docs/books/tutorial/rmi/index.html

《精通 EJB 》第二版 附录 A

 

 

 

: 代码请参考 java 核心技术》第 7 第五章 分布式对象 中的Product例子中的代码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值