通俗来讲RPC(Remote Procedure Call)就是调用远程的过程或者方法,既然涉及到远程,必然会有C/S架构,即client和server。下面首先来看一下Client端的实现。
为实现远程方法调用,最重要的就是跟远程服务器进行连接,然后不断的传输客户端想要调用的方法,包括方法的参数等。为此Client有两个最重要的变量与之一一对应,Connection和Call。其中,Connection代表与远程服务器之间的连接;Call是一个方法调用的抽象。Connection有一个队列,保存所有需要到该Connection对应的服务器进行调用的方法。因为一个Client可能同时需要到多个服务器进行方法调用,如HDFS一次文件操作,不但需要跟NameNode进行通信,还需要与DataNode进行通信;因此,Client会包含一个Connection的队列。为了区分不同的Connection,Client定义了另外一个Class ConnectionId来标识不同的连接。
下面我看一下Call的实现,Call具体是比较简单的,如下代码:
private class Call {
int id; // call id
Writable param; // parameter
Writable value; // value, null if error
IOException error; // exception, null if value
boolean done; // true when call is done
protected Call(Writable param) {
this.param = param;
synchronized (Client.this) {
this.id = counter++;
}
}
......
下面jurisdiction解析一下其不同成员变量的意义,id是在同一个connection上不同方法调用的标识;param是client传向服务器端的数据,一会具体分析;value是返回结果。其中我们具体分析一下param,在Call中param的具体实现是Class Invocation,Invocation具体代表了一个方法,其实现如下:
private static class Invocation implements Writable, Configurable {
private String methodName;
private Class[] parameterClasses;
private Object[] parameters;
private Configuration conf;
......
其中,methodName代表远程调用的方法的名字;parameterClasses代表传入方法参数的类型;parameters代表传入方法参数的值。
如此结合另外一篇文件《Hadoop RPC整个使用流程——以DataNode 向NameNode注册为例》则整个RPC的过程就比较容易理解了。