zoukankan      html  css  js  c++  java
  • Hdoop日记Day10---RPC机制

    一、RPC(Remote Procedure Call)简介

    RPC远程过程调用(Remote Procedure Call),即远程调用其他虚拟机中运行的javaobject。RPC 是一种客户端/服务器模式,那么在使用时包括服务端代码客户端代码,还有我们调用的远程过程对象。HDFS 的运行就是建立在此基础之上的。本章通过分析实现一个简单的RPC 程序来分析HDFS 的运行机理。

    二、代码解析

    1. 服务端代码

       代码如下:

    1  public class MyServer {
    2     public static final int SERVER_PORT = 12345;
    3     public static final String SERVER_ADDRESS = "localhost";
    4     public static void main(String[] args) throws IOException {
    5     final Server server = RPC.getServer(new MyBiz(), SERVER_ADDRESS,
    6       SERVER_PORT, new Configuration());
    7   server.start();
    8     }
    9 }

    核心在于第5 行的RPC.getServer 方法,该方法有四个参数:

    第一个参数是被调用的java服务对象。

    第二个参数是服务器的地址。

    第三个参数是服务器的端口。

    获得服务器对象后,启动服务器。这样,服务器就在指定端口监听客户端的请求。

    2. 被调用的远程对象类

    代码如下:

     1 public class MyBiz implements MyBizable{
     2     public static long BIZ_VERSION = 2345234L;
     3     @Override
     4     public String hello(String name){
     5         System.out.println("我被调用了");
     6         return "hello "+name;
     7     }
     8     @Override
     9     public long getProtocolVersion(String protocol, long clientVersion)
    10     throws IOException {
    11         return BIZ_VERSION;
    12     }
    13 }    

    被调用的远程对象实现了接口MyBizable,这里面有两个方法被实现,一个就是hello方法,另一个是getProtocalVersion 方法。这个hello 方法内部有个输出语句

    3. 远程调用类的接口

    代码如下:

    1 public interface MyBizable extends VersionedProtocol{
    2     public abstract String hello(String name);
    3 }

    这个接口中的方法就是刚才的Biz 中实现的方法。接口继承的VersionedProtocal,是hadoop 的RPC 的接口,所有的RPC 通信必须实现这个一接口,用于保证客户端和服务端的端口一致。服务端被调用的类必须继承这个接口VersionedProtocal。

    4. 客户端代码,这里使用的调用对象的接口

    代码如下:

     1 public class MyClient {
     2     public static void main(String[] args) throws Exception {
     3     final MyBizable proxy = (MyBizable)RPC.getProxy(MyBizable.class,
     4    MyBiz.BIZ_VERSION, new InetSocketAddress(MyServer.SERVER_ADDRESS,
     5     MyServer.SERVER_PORT), new Configuration());
     6   //调用接口中的方法
     7   final String result = proxy.hello("world");
     8   System.out.println(result);
     9   //本质是关闭网络连接
    10    RPC.stopProxy(proxy);
    11   }
    12 }

    以上代码中核心在于RPC.getProxy(),该方法有四个参数:

    第一个参数是被调用的接口类。

    第二个是客户端版本号。

    第三个是服务端地址。

    返回的代理对象,就是服务端对象的代理,内部就是使用java.lang.Proxy 实现的。运行时,先启动服务端,再启动客户端。读者可以在服务端和客户端输出信息。
    从上面的RPC 调用中,可以看出:在客户端调用的业务类的方法是定义在业务类的接口中的。该接口实现了VersionedProtocal 接口

    5. 现在我们在命令行执行jps 命令查看输出信息

    如图2.1 所示。

    图 2.1

    可以看到一个java 进程,是“MyServer”,该进程正是我们刚刚运行的rpc 的服务端类MyServer。大家可以联想到我们搭建hadoop 环境时,也执行过该命令用来判断hadoop 的进程是否全部启动。那么可以判断,hadoop 启动时产生的5 个java 进程也应该是RPC 的服务端。我们观察NameNode 的源代码,我们可以看到如图下代码,可以看到NameNode 确实创建了RPC 的服务端。

     1   // create rpc server
     2     InetSocketAddress dnSocketAddr = getServiceRpcServerAddress(conf);
     3     if (dnSocketAddr != null) {
     4       int serviceHandlerCount =
     5         conf.getInt(DFSConfigKeys.DFS_NAMENODE_SERVICE_HANDLER_COUNT_KEY,
     6                     DFSConfigKeys.DFS_NAMENODE_SERVICE_HANDLER_COUNT_DEFAULT);
     7       this.serviceRpcServer = RPC.getServer(this, dnSocketAddr.getHostName(), 
     8           dnSocketAddr.getPort(), serviceHandlerCount,
     9           false, conf, namesystem.getDelegationTokenSecretManager());
    10       this.serviceRPCAddress = this.serviceRpcServer.getListenerAddress();
    11       setRpcServiceServerAddress(conf);
    12     }
  • 相关阅读:
    bzoj1096: [ZJOI2007]仓库建设
    bzoj3289: Mato的文件管理
    bzoj1878: [SDOI2009]HH的项链
    bzoj1295: [SCOI2009]最长距离
    bzoj1056: [HAOI2008]排名系统 && 1862: [Zjoi2006]GameZ游戏排名系统
    vijosP1026毒药?解药?
    bzoj1293: [SCOI2009]生日礼物
    bzoj1483: [HNOI2009]梦幻布丁
    PCB开窗
    3W原则
  • 原文地址:https://www.cnblogs.com/sunddenly/p/3983193.html
Copyright © 2011-2022 走看看