本文共 3321 字,大约阅读时间需要 11 分钟。
RPC(Remote Procedure Call Protocol)远程过程调用协议。一个通俗的描述是:客户端在不知道调用细节的情况下,调用存在于远程计算机上的某个方法,就像调用本地应用程序中的对象一样。同时将网络的通信细节隐藏起来,使得用户无需额外的关注交互过程,由于RPC大大简化了分布式程序的开发,因此备受欢迎。
RPC通常用C/S模式。请求程序是一个客户机,服务提供程序是一个服务器。一个典型的RPC框架如下图所示:
Hadoop摒弃了Java原生重量级RPC框架RMI,根据实际场景的需要实现了一个自己的RPC框架。该框架具有如下特点:
架构体系
hadoop RPC分为四个部分。Hadoop RPC对外主要提供了两种接口(见类org.apache.hadoop.ipc.RPC),分别是:
RPC使用步骤:
定义RPC协议
RPC协议是客户端和服务器端之间的通信接口,它定义了服务器对外提供的服务接口。新建文件IRPCInterface.java。public interface IRPCInterface extends VersionedProtocol { long versionID = 1; //版本号,默认情况下不同版本号之间的server和client不能通信。 int add(int a, int b) throws IOException;}
实现RPC协议
上面实现了协议的“骨架”:接口,现在针对接口进行具体的实现。新建IRPCInterfaceImpl.java文件。
``` class IRPCInterfaceImpl implements IRPCInterface {@Overridepublic int add(int a, int b) { return a + b;}@Overridepublic long getProtocolVersion(String s, long l) throws IOException { return IRPCInterface.versionID;}@Overridepublic ProtocolSignature getProtocolSignature(String s, long l, int i) throws IOException { return new ProtocolSignature(IRPCInterface.versionID,null);}
}
```构造并启动RPC Server
使用静态类Builder构造一个RPC Server,并调用start()启动server。新建RpcServer.java。import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.ipc.ProtocolSignature;import org.apache.hadoop.ipc.RPC;import org.apache.hadoop.ipc.RPC.Server;public class RpcServer { public static void main(String[] args) throws IOException { Server server = new RPC.Builder(new Configuration()). setBindAddress("127.0.0.1").setPort(8080). setInstance(new IRPCInterfaceImpl()). setProtocol(IRPCInterface.class).build(); server.start(); }}
构造RPC Client并发送RPC请求
使用静态方法getProxy构造客户端代理对象,直接通过代理对象调用远程方法。新建RpcClient.java文件。import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.ipc.RPC;import java.io.IOException;import java.net.InetSocketAddress;public class RpcClient { public static void main(String[] args) throws IOException { IRPCInterface proxy = RPC.getProxy(IRPCInterface.class, 1, new InetSocketAddress("127.0.0.1", 8080), new Configuration()); int result = proxy.add(1,2); System.out.println("result = " + result); }}
运行