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:通信双方所遵循契约的父接口;
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(); } }
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); } }