六、RPC基本原理

[TOC]

一、RPC基本概念

1、RPC是什么

​ 所谓的RPC其实是为了不同主机的两个进程间通信而产生的,通常不同的主机之间的进程通信,那么程序编写则需要考虑到网络通信的功能,这样程序的编写将会变得复杂。而RPC就是报文交换的一种机制,一台主机上的进程对另外一台主机的进程发起请求时,内核会将请求转交给RPC client,RPC client经过报文的封装转交给目标主机的RPC server,RPC server就将报文进行解析,还原成正常的请求,转交给目标主机上的目标进程。所以在两台主机的两个进程看来,就像是在同一台主机上的两个进程通信一样,完全没有意识到是在不同的主机上。所以说RPC其实也是一种协议或者是编程框架,简化了分布式程序的编写。
​ 而hadoop作为一个典型的分布式项目,跨主机调用服务的情况很常见(并非http服务)。我们要清楚一点,通过http这些restfulapi的方式暴露的服务,调用者是明显知道被调用者是在不同的主机上。而通过RPC调用的话,在调用者看来,他以为被调用者是在同一台主机上的,但是实际上是在不同主机上的。

2、RPC基本流程

六、RPC基本原理

1、首先调用方需要有个RPCclient,被调用方需要有 RCPServer,这两个服务用于RPC通信。
2、调用者通过RPCClient调用指定方法,RPCClient则将请求封装后(将方法参数值进行二进制序列化),传递给server
3、server收到请求后,反序列化参数,恢复成请求原本的形式,然后找到对应的方法进行本地调用。将方法的返回值通过RPC返回给client
4、client收到结果后,将结果返回给调用者作为返回值。

二、hadoop的RPC

1、hdfs的RPC基本流程

六、RPC基本原理

hdfs的rpc流程基本如上,其中的关键就是获得NameNode代理对象。

2、java中的代理方式

(1)静态代理
先定义一个公共接口,里面包括了可以通过RPC调用的方法列表。而且被代理对象以及对象本身都需要实现该接口

(2)动态代理
先定义一个公共接口,里面包括了可以通过RPC调用的方法列表。被代理对象以及对象本身都不需要实现该接口。而是通过匿名内部类+反射的机制实现。hadoop就是使用这种方式

3、hadoop rpc框架的例子

例子结构:

Server
    MyImpl.java         server本地执行的方法的具体实现代码
    MyInterface.java    可以rpc执行的方法列表
    MyRpcServer.java    rpc server端
Client
    MyRpcClient.java    rpc client端

Server:

/*
MyInterface.java    
*/
package Server;

import org.apache.hadoop.ipc.VersionedProtocol;

public interface MyInterface extends VersionedProtocol {
    public static long versionID = 1001; //这个是标记RPC的client和server对应的标记
    public String helloWorld(String name);
}

/*
MyImpl.java
*/
package Server;

import org.apache.hadoop.ipc.ProtocolSignature;

import java.io.IOException;

public class MyImpl implements MyInterface{
    /*这是实际目标*/

    //重写我们在上面接口自定义的方法
    @Override
    public String helloWorld(String name) {
        return "hello," + name;
    }

    //返回版本号
    @Override
    public long getProtocolVersion(String s, long l) throws IOException {
        return MyInterface.versionID;
    }

    //返回签名信息
    @Override
    public ProtocolSignature getProtocolSignature(String s, long l, int i) throws IOException {
        return new ProtocolSignature(MyInterface.versionID, null);
    }
}

/*
MyRpcServer.java
*/
package Server;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.ipc.RPC;

import java.io.IOException;

public class MyRpcServer {
    public static void main(String[] args) {
        //建立rpc通道对象
        RPC.Builder builder = new RPC.Builder(new Configuration());

        //设置RPC server参数
        builder.setBindAddress("localhost");
        builder.setPort(7788);

        //部署程序,传入实现server业务代码的接口定义,这里面包括了该rpcserver 可以提供的方法,也就是给client调用的方法列表,通过反射的方式引入类对象
        builder.setProtocol(MyInterface.class);

        //部署接口的实现类对象
        builder.setInstance(new MyImpl());

        //开启server
        try {
            RPC.Server server = builder.build();
            server.start();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

client:

/*
MyRpcClient.java
*/
package Client;

import Server.MyInterface;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.ipc.RPC;

import java.io.IOException;
import java.net.InetSocketAddress;

public class MyRpcClient {
    public static void main(String[] args) {
        try {
            //获取代理对象,设置接口类对象、RPC通信的versionID,rpcserver地址、configuration对象
            MyInterface proxy = RPC.getProxy(
                    MyInterface.class,
                    MyInterface.versionID,
                    new InetSocketAddress("localhost", 7788),
                    new Configuration());

            //获得代理对象之后,就可以通过proxy调用接口类中的方法,这里就调用上面定义的 helloWorld对象
            System.out.println(proxy.helloWorld("king"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

下面启动server端和client端,执行结果为:

//server:可以看到显示监听端口 7788
[main] INFO org.apache.hadoop.ipc.CallQueueManager - Using callQueue: class java.util.concurrent.LinkedBlockingQueue queueCapacity: 100 scheduler: class org.apache.hadoop.ipc.DefaultRpcScheduler
[Socket Reader #1 for port 7788] INFO org.apache.hadoop.ipc.Server - Starting Socket Reader #1 for port 7788
[IPC Server Responder] INFO org.apache.hadoop.ipc.Server - IPC Server Responder: starting
[IPC Server listener on 7788] INFO org.apache.hadoop.ipc.Server - IPC Server listener on 7788: starting

//client:  我们传入“King”作为参数,能够争取执行
hello,king

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/192180.html

(0)
上一篇 2021年11月14日
下一篇 2021年11月14日

相关推荐

发表回复

登录后才能评论