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. OnCreateContextMenuListener接口简介

    OnCreateContextMenuListener接口是用来处理上下文菜单显示事件的监听接口.该方法是定义和注册上下文菜单的另一种方式.该接口中事件处理的回调方法签名如下所示. public vo ...

  2. main方法之args参数

    public class Demo { public static void main (String[] arr) { if (arr.length < 3) { System.out.pri ...

  3. ui-sref的参数传递

    例如:路由配置如下: $stateProvider.state('admin.userList', { url: '/listUser?type&role', //参数必须先在这边声明 tem ...

  4. leetCode题解之反转二叉树

    1.题目描述 经典的反转二叉树,就是将二叉树中每个节点的左.右儿子交换. 2.题目分析 3.代码 TreeNode* invertTree(TreeNode* root) { if(root == N ...

  5. 机器学习之step by step实战及知识积累笔记

    数据工作者工作时间划分 据crowdflower数据科学研究报告,数据科学工作者的时间分配主要在以下几个领域: 首先是数据收集要占20%左右的时间和精力,接着就是数据清洗和再组织需要占用60%的时间. ...

  6. 【转】stropts.h: No such file or directory – How to Fix

    原文地址:stropts.h: No such file or directory – How to Fix 作者:xjc2694 It is a known issue that modern Li ...

  7. How To Change Log Rate Limiting In Linux

    By default in Linux there are a few different mechanisms in place that may rate limit logging. These ...

  8. django新建项目,连接mysql数据库

    安装django,进入Django目录,运行 python setup.py install 在workplace目录下新建一个名为site01的项目: cd workplacedjango-admi ...

  9. Codewars, Leetcode, Hackerrank. Online Judges Reviews

    http://jasonjl.me/blog/2015/03/30/practical-programming-practice-services/ Codewars, Leetcode, Hacke ...

  10. Python学习---IO的异步[自定义异步IO]

    自定义IO异步基础知识: --所有的请求都基于socket实现,一个请求就是一个socket socket.setblocking(False) 不需要阻塞,一个请求完了发送另外一个,会报错,需解决 ...