Hadoop RPC 远程过程调用是Hadoop中的核心概念。在深入研究RPC之前,先看看远程调用的鼻祖Java RMI.
Java远程方法调用,即Java RMI(Java Remote Method Invocation)是Java编程语言里,一种用于实现远程过程调用的应用程序编程接口。它使客户机上运行的程序可以调用远程服务器上的对象。远程方法调用特性使Java编程人员能够在网络环境中分布操作。RMI全部的宗旨就是尽可能简化远程接口对象的使用。
Java RMI极大地依赖于接口。在需要创建一个远程对象的时候,程序员通过传递一个接口来隐藏底层的实现细节。客户端得到的远程对象句柄正好与本地的根代码连接,由后者负责透过网络通信。这样一来,程序员只需关心如何通过自己的接口句柄发送消息。
接口的两种常见实现方式是:
(1)最初使用JRMP(Java Remote Message Protocol,Java远程消息交换协议)实现;
(2)此外还可以用与CORBA兼容的方法实现。
RMI一般指的是编程接口,也有时候同时包括JRMP和API(应用程序编程接口),而RMI-IIOP则一般指RMI接口接管绝大部分的功能,以支持CORBA的实现。最初的RMI API设计为通用地支持不同形式的接口实现。后来,CORBA增加了传值(pass by value)功能,以实现RMI接口。然而RMI-IIOP和JRMP实现的接口并不完全一致。
RMI相关的类和接口都在jdk
java.rmi
包中。
RMI的基础是接口,RMI构架基于一个重要的原理:定义接口和定义接口的具体实现是分开的。
下面我们通过具体的例子,建立一个简单的远程计算服务和使用它的客户程序
一个正常工作的RMI系统由下面几个部分组成:
远程服务的接口定义
远程服务接口的具体实现
Stub 和 Skeleton 文件
一个运行远程服务的服务器
一个RMI命名服务,它允许客户端去发现这个远程服务
类文件的提供者(一个HTTP或者FTP服务器)
一个需要这个远程服务的客户端程序
下面我们一步一步建立一个简单的RMI系统。首先在你的机器里建立一个新的文件夹,以便放置我们创建的文件,为了简单起见,我们只使用一个文件夹存放客户端和服务端代码,并且在同一个目录下运行服务端和客户端。如果所有的RMI文件都已经设计好了,那么你需要下面的几个步骤去生成你的系统:
1、 编写并且编译接口的Java代码
2、 编写并且编译接口实现的Java代码
3、 从接口实现类中生成 Stub 和 Skeleton 类文件
4、 编写远程服务的主运行程序
5、 编写RMI的客户端程序
6、 安装并且运行RMI系统
第一步就是建立和编译服务接口的Java代码。这个接口定义了所有的提供远程服务的功能,下面是源程序:
/** * */ package com.renren; import java.rmi.Remote; import java.rmi.RemoteException; /** * @author root * */ public interface CalculatorRemoteInterface extends Remote { //! 注意,这个接口继承自Remote,每一个定义的方法都必须抛出一个RemoteException异常对象 public abstract int add(int a, int b) throws RemoteException; }
注意,这个接口继承自Remote,每一个定义的方法都必须抛出一个RemoteException异常对象
package com.renren; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; @SuppressWarnings("serial") // 继承 UnicastRemoteObject 远程对象 这个一定要写 否则 服务器启动报异常 public class CalculatorRemoteObject extends UnicastRemoteObject implements CalculatorRemoteInterface { public CalculatorRemoteObject() throws RemoteException { super(); // TODO Auto-generated constructor stub } /** * */ private static final long serialVersionUID = 1L; // @Override public int add(int a, int b) { // TODO Auto-generated method stub return a + b; } }
将上述两个java文件编译打包为rmi-test.jar
在编写server和client程序时需要依赖该jar包
Server做的事很简单,代码注释很详细...
package com.test; import java.net.MalformedURLException; import java.rmi.AlreadyBoundException; import java.rmi.Naming; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; public class Server { public static void main(String[] args) { // TODO Auto-generated method stub try { // 定义远程接口CalculatorRemoteInterface对象 用于绑定在服务器注册表上 该接口由CalculatorRemoteObject类实现 CalculatorRemoteInterface remoteObject = new CalculatorRemoteObject(); // 定义一个端口号 int port = 9999; // 创建一个接受对特定端口调用的远程对象注册表 注册表上需要接口一个指定的端口号 LocateRegistry.createRegistry(port); // 定义服务器远程地址URL格式 String serverAddress = "rmi://10.2.185.197:" + port+"/calculator" ; // 绑定远程地址和接口对象 Naming.bind(serverAddress, remoteObject); // 如果启动成功 则弹出如下信息 System.out.println(">>>服务器启动成功"); System.out.println(">>>请启动客户端进行连接访问"); } catch (MalformedURLException e) { System.out.println("地址出现错误!"); e.printStackTrace(); } catch (AlreadyBoundException e) { System.out.println("重复绑定了同一个远程对象!"); e.printStackTrace(); } catch (RemoteException e) { System.out.println("创建远程对象出现错误!"); e.printStackTrace(); } } }
package com.test; import java.net.MalformedURLException; import java.rmi.Naming; import java.rmi.NotBoundException; import java.rmi.RemoteException; public class Client { public static void main(String[] args) { // TODO Auto-generated method stub try { CalculatorRemoteInterface calculator= (CalculatorRemoteInterface) Naming.lookup("rmi://10.2.185.197:9999/calculator"); System.out.println("5+3="+calculator.add(5, 3)); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NotBoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
1.在一台机器上启动Server
2.在两外一台机器上启动Client,可以看到Client成功调用了Server的CalculatorRemoteObject对象的add方法.
参考:
http://blog.csdn.net/wangxingbao4227/article/details/6842951
http://blog.csdn.net/tin591/article/details/8117198
http://hi.baidu.com/dl_linfeng/item/330036304422c65c80f1a778
Hadoop RPC详解-RMI,布布扣,bubuko.com
原文:http://blog.csdn.net/mango_song/article/details/21649089