RPC(Remote Procedure Call, 远程过程调用)是一种通过网络从远程计算机上请求服务来得到计算服务或者数据服务,且不需要了解底层网络技术的协议和框架。

RPC远程调用是构建在语言级别的,必须使用Socket通信完成,将现有的本地方法调用和Socket网络通信技术结合起来实现透明的远程调用过程。实现透明的远程调用重点是创建客户存根(client stub),存根(stub)就像代理(agent)模式里的代理(agent),在生成代理代码后,代理代码与远程服务端通信,通信过程由RPC框架实现,调用者像调用本地代码一样方便。在客户端看来,存根函数像普通本地函数一样,实际包含了网络发送和接收消息的代码。具体过程如下图所示。

  1. 客户端调用本地客户端的存根方法(client stub),将参数打包并封装成一个或多个网络消息体,这个过程被称为编码(encode),它会将所有数据序列化成字节数组格式;

  2. client stub通过系统调用,使用操作系统内核提供的Socket套接字接口来向远程服务发送编码的网络消息;

  3. 网络消息由内核通过网络协议(无连接协议:UDP, 或面向连接的协议:TCP)传输到远程服务端;

  4. 服务端存根(server stub)接收客户端发送的消息,并对参数消息进行解码(decode),通常它会将参数从标准的网络格式转换成特定的语言格式;

  5. server stub调用服务端方法,并将从客户端接收的参数传递给该方法;

  6. 服务端方法执行具体的功能并返回,此部分代码的执行对客户端而言就是远程过程调用;

  7. 服务端在方法执行完后,讲结果返回到服务端存根代码中;

  8. 服务端存根在降该返回值进行编码并序列化后,通过一个或多个网络消息发送给客户端;

  9. 消息通过网络发送到客户端存根;

  10. 客户端存根从本地Socket接口中读取结果消息;

  11. 客户端存根将结果返回给客户端函数,并将消息从网络二进制形式转换为本地语言格式,这样就完成了远程服务调用,客户端代码继续执行后续操作。

Socket套接字:网络上两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端被称为Socket。Socket用于描述IP地址和端口,是一个通信连接的句柄,可以用来实现不同计算机之间的通信,是网络编程接口的具体实现。

Socket是客户端/服务端网络结构程序的基本组成部门,为程序提供了一种相对简单的机制与远程机器上的程序建立连接,并来回发送消息。基于这些收发功能,将RPC的调用包装成透明的远程服务调用。

HDFS的底层通信是通过RPC和动态代理对象Proxy实现的。Hadoop RPC的使用方法分为以下几步:

  1. 定义RPC协议。RPC协议是客户端和服务器之间的通信接口,它定义了服务器对外提供的服务接口;

  2. 实现RPC协议。Hadoop RPC是一个Java接口,需要用户实现。

  3. 构造并启动RPC Server。直接使用静态方法getServer()构造一个RPC Server,并调用start()方法启动该Server。

  4. 构造RPC Client,并发送RPC请求。使用静态方法getProxy()构造客户端代理对象,直接通过代理对象调用远程端的方法。

HDFS RPC代码示例:

服务端代码

package beichen.rpc.server;
import org.apache.hadoop.ipc.VersionedProtocol;
public interface MyInterface extends VersionedProtocol{    
  //定义一个版本号,使用版本号来进行签名
  
  public static long versionID = 1;  

  //定义业务方法

  public String sayHello(String name);
}

package beichen.rpc.server;
import java.io.IOException;
import org.apache.hadoop.ipc.ProtocolSignature;
public class MyInterfaceImpl implements MyInterface {
@Override
  public String sayHello(String name) {

  System.out.println("*********调用到了Server 端**********");

  return "Hello "+name;

  }

@Override
public ProtocolSignature getProtocolSignature(String arg0, long arg1, int arg2) throws IOException {

  //通过版本号定义签名信息

  return new ProtocolSignature(MyInterface.versionID, null);

}

@Override
  public long getProtocolVersion(String arg0, long arg1) throws IOException {

  //返回版本号

  return MyInterface.versionID;

  }
}
package beichen.rpc.server;
import java.io.IOException;
import org.apache.hadoop.HadoopIllegalArgumentException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.ipc.RPC;
import org.apache.hadoop.ipc.RPC.Server;
public class MyRPCServer {   public static void main(String[] args) throws Exception
  {

    //利用Hadoop RPC的框架实现RPC Server,使用RPC Builder来构建

    RPC.Builder builder = new RPC.Builder(new Configuration());

    //定义Server的参数

    builder.setBindAddress("localhost");

    builder.setPort(7788);

    //部署程序

    builder.setProtocol(MyInterface.class);
    //部署的接口

    builder.setInstance(new MyInterfaceImpl());
    //指定接口的实现类

    // 创建RPC Server

    Server server = builder.build();

    //启动Server

    server.start();

  }
}

客户端代码

package beichen.rpc.client;
import java.io.IOException;
import java.net.InetSocketAddress;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.ipc.RPC;
import beichen.rpc.server.MyInterface;
public class MyRPCClient {
  // 使用Hadoop RPC的框架调用Server 端的程序

  public static void main(String[] args) throws Exception {

    //得到的是Server端部署对象的代理对象

    MyInterface proxy = RPC.getProxy(MyInterface.class,
  MyInterface.versionID,
  new InetSocketAddress("localhost", 7788),
                   
new Configuration());     //使用这个代理对象调用Server的程序
    String result = proxy.sayHello("Tom");

    System.out.println(result);

   }
}

RPC--HDFS节点间的沟通桥梁的更多相关文章

  1. React数据流和组件间的沟通总结

    今天来给大家总结下React的单向数据流与组件间的沟通. 首先,我认为使用React的最大好处在于:功能组件化,遵守前端可维护的原则. 先介绍单向数据流吧. React单向数据流: React是单向数 ...

  2. React的单向数据流与组件间的沟通

    今天来给大家总结下React的单向数据流与组件间的沟通. 首先,我认为使用React的最大好处在于:功能组件化,遵守前端可维护的原则. 先介绍单向数据流吧. React单向数据流: React是单向数 ...

  3. 集群节点间网络通信TIPC

    1. TIPC背景介绍 TIPC主要是用于集群网络环境之中,它这个协议有一些前提假设包括: 协议发送的大部分message都是直接到达目的地(无路由): message的传输时间都很短; messag ...

  4. galera cluster DDL节点间状态不一致的问题

    近期某个系统中的galera cluseter环境发生A DDL操作后,B节点未同步的情况,同时B节点的errorlog中有如下警告信息: 2016-07-23 17:31:32 18920 [War ...

  5. 基于CentOS与VmwareStation10搭建Oracle11G RAC 64集群环境:4.安装Oracle RAC FAQ-4.3.Oracle 集群节点间连通失败

    1.检查节点连通性的错误 [grid@linuxrac1 grid]$ ./runcluvfy.sh stage -post hwos -n linuxrac1,linuxrac2 -verbose ...

  6. Cassandra1.2文档学习(2)——节点间通信协议之gossip协议

    参考文档:http://www.datastax.com/documentation/cassandra/1.2/webhelp/index.html#cassandra/architecture/a ...

  7. RAC 安装完成后 节点间通信不依赖于SSH

    RAC 安装完成后,想修改ssh 的端口.google了一下.原文https://community.oracle.com/thread/2444594?tstart=0 原文说的是11g,10g也好 ...

  8. JavaScript---网络编程(7)-Dom模型(节点间的层次关系,节点的增、删、改)

    利用节点间的层次关系获取节点: 上一节讲了3中获取的方式: * ※※一.绝对获取,获取元素的3种方式:-Element * 1.getElementById(): 通过标签中的id属性值获来取该标签对 ...

  9. dfs 无向图两节点间的所有路径

    标题:风险度量 X星系的的防卫体系包含 n 个空间站.这 n 个空间站间有 m 条通信链路,构成通信网.两个空间站间可能直接通信,也可能通过其它空间站中转. 对于两个站点x和y (x != y), 如 ...

随机推荐

  1. 润乾报表一个页面中的echarts地图与其他区块的联动

    需求概述: DBD样式效果如下图所示,需要点击左侧地图中的地区,右侧的仪表盘,柱线图可以对应显示对应该地区的数据. 实现思路: 分别制作带有地图.仪表盘.柱线图的3张报表:将3张报表放到DBD中设置布 ...

  2. 报表在vista和win7下无法浏览应用的解决办法

     对于vista和win7系统,报表工具有着良好的兼容性,无论是设计器还是实际应用.有些客户在安装报表设计报表的时候没有遇到问题,但是在这两种系统下会发现无法启动应用,或者打开设计器自带的ie浏览 ...

  3. Condition使用

    面试题:写一个固定容量同步容器,拥有put和get方法,以及getCount方法,    能够支持2个生产者线程以及10个消费者线程的阻塞调用 有两种方法 1.使用wait和notify/notify ...

  4. linux rabbitmq 安装

    下载 在安装 erlang 时使用的是源码包21.0版本:接着下载 rabbitmq-server/3.7.7 的源码包,编译时报错,说 erlang 版本号不满足条件,erlang版本>=19 ...

  5. Pig的使用场景

    数据转换加载(ETL)数据流:读取原始数据(比如用户日志),进行数据清洗,进行简单的预计算后导入到数据仓库,比如join连接数据库里的用户信息.

  6. Django ORM字段类型 单表增删改查 万能的双下划线

    1.ORM三种模型 模型之间的三种关系:一对一,一对多,多对多. 一对一:实质就是在主外键(author_id就是foreign key)的关系基础上,给外键加了一个UNIQUE=True的属性: 一 ...

  7. 【日常记录】用 vs2015 编译 love2d 引擎时出现 依赖项目luajit编译失败的解决办法

    如图片所示,提示是没有找到cmake命令.看来是需要camke软件支持的,由于当初安装CMake后我重装了系统,也没有把cmake的bin路径 解决办法一:重新安装CMake,并勾选上"ad ...

  8. SQLSERVER:PREEMPTIVE_OS_GETPROCADDRESS等待类型的困惑

    SQLSERVER:PREEMPTIVE_OS_GETPROCADDRESS等待类型的困惑 翻译自:http://troubleshootingsql.com/2011/07/20/preemptiv ...

  9. [book] iOS 8 Swift Programming Cookbook

    iOS 8 Swift Programming Cookbook 资源地址 http://pan.baidu.com/s/1c0hn1Gc 书籍介绍 源码截图 书籍截图

  10. $.ajax 在请求没有完成,是可以往下继续执行js代码的

    $.ajax({ url:url, data:{}, success:function(arr) { var varHtml='<option value="" checke ...