Hadoop2.4.1 RPC实现的底层原理(一)

来源:互联网 发布:办公室饿 知乎 编辑:程序博客网 时间:2024/06/05 05:26

RPC是远程过程调用(Remote Procedure Call),即远程调用其他虚拟机中运行的java object。RPC是一种客户端/服务器模式,那么在使用时包括服务端代码和客户端代码,还有我们调用的远程过程对象。简单的理解可以看下图:


Hadoop的RPC主要是通过Java的动态代理与反射实现,代理类是由java.lang.reflect.Proxy类在运行期时根据接口,采用Java反射功能动态生成的,并且结合java.lang.reflect.InvocationHandler来处理客户端的请求,当用户调用这个动态生成的实现类时,实际上是调用了InvocationHandler实现类的invoke方法。RPC源代码在org.apache.hadoop.ipc下,有以下几个主要类:

Client: 客户端,连接服务器、传递函数名和相应的参数、等待结果;

Server:服务器端,主要接受Client的请求、执行相应的函数、返回结果;

VersionedProtocol:通信双方所遵循契约的父接口;

RPC:RPC通信机制,主要是为通信的服务方提供代理。

我们可以看到,客户端和服务端进行通信,双方必须遵循一个契约。这个契约就是规定了双方之间可以干什么和不能干什么。
现在我们暂时做太多原理上的解释和源码上的分析,后面我会一一讲解,现在我们通过一个小例子来体会一下Hadoop的RPC。
我们暂时不使用hadoop给我们提供的契约,我们自己定义一个契约。我的服务端的程序是写在linux环境中的,项目名称叫做hadoop-rpc-server.客户端程序是写在windows环境中的,项目的命中叫做hadoop-rpc-client.同时ServerClientProtocol契约服务端和客户端双发必须都持有。
一、服务端
契约接口:
package com.npf.hadoop.rpc;public interface LoginService {        public static final long versionID = 1L;        public String login(String username,String password);}

契约接口的实现类:
package com.npf.hadoop.rpc;public class LoginServiceImpl implements LoginService {        @Override        public String login(String username, String password) {                return username+" login successfully.";        }}

服务的启动类:
package com.npf.hadoop.rpc;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 ServerStart {        public static void main(String[] args) throws HadoopIllegalArgumentException, IOException {                                RPC.Builder builder = new RPC.Builder(new Configuration());                                builder.setInstance(new LoginServiceImpl()).setBindAddress("uatciti").setPort(9999).setProtocol(LoginService.class);                                Server server = builder.build();                                server.start();        }}

运行ServerStart程序,就说明我们的服务器已经启动了。

二、客户端
契约接口,和服务端一模一样。
package com.npf.hadoop.rpc;public interface LoginService {public static final long versionID = 1L;public String login(String username, String password);}

调用服务器提供的服务:
package com.npf.hadoop.rpc;import java.io.IOException;import java.net.InetSocketAddress;import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.ipc.RPC;public class UserLoginController {public static void main(String[] args) throws IOException {Configuration conf = new Configuration();LoginService proxy = RPC.getProxy(LoginService.class, 1L,new InetSocketAddress("uatciti", 9999), conf);String result = proxy.login("zhangsan", "123456");System.out.println(result);}}

运行结果:



0 0