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. Metinfo 5.x 管理员密码重置漏洞

    前言 在先知看到了一篇分析该漏洞的文章,复现分析一下,漏洞还是比较有趣的. 正文 首先知道是 管理员密码重置时出现的问题,于是抓包,定位到相关的php文件. 首先包含了 ../include/comm ...

  2. Vue 框架-10-搭建脚手架 CLI

    Vue 框架-10-搭建脚手架 CLI + 批处理快捷启动 脚手架是通过 webpack 搭建的开发环境 使用 ES6 语法 打包和压缩 JS 为一个文件 项目文件在环境中,而不是浏览器 实现页面自动 ...

  3. mysql 字符串函数、分组函数

    字符串函数 1.concat 函数 drop table test;create table test(id int(4), name varchar(10), sex char(2));insert ...

  4. 【Python】Java程序员学习Python(六)— 流程控制、异常处理

    和Java语言一样,Python也有基本的流程控制,简单了解下即可. 一.流程控制的元素 条件 条件就是布尔值或者布尔值的表达式,要么是True要么是False. 代码块 在Python中,代码块不是 ...

  5. asp.net(C#)常用时间日期处理类

    using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Secu ...

  6. 【涨姿势】Prince2和PMP的区别,大多数人都没搞清楚!

    项目管理领域有2个流行的知识体系:      ☑ 一个是美国项目管理协会(PMI)开发的“项目管理知识体系(PMBOK,Project Management Body of Knowledge)”,目 ...

  7. centos6 安装glibc-2.14.1

    CentOS默认的glibc版本为2.12.1, 网上都是给出的升级至glibc-2.14.1的方法, 都是用glibc-2.14.1.tar.gz [root@192-168-0-151 ~]# s ...

  8. December 01st 2016 Week 49th Thursday

    Life is a maze and love is a riddle. 生活是个迷宫,爱情是个谜语. I am lost in both. Can you provide me some guida ...

  9. ACE.js自定义提示实现方法

    ACE.js自定义提示实现方法 时间 2015-11-19 00:55:22  wsztrush's blog 原文  http://wsztrush.github.io/编程技术/2015/11/0 ...

  10. 预估高并发下API服务器数量

    我的主要工作就是API的编写,应该关注API的响应时间,以及并发时候的响应.那么如何测试API响应时间,以及预计高并发服务器压力呢? 从访问日志开始查起. 1 首先统计API每日访问总数.举例假设某个 ...