Hadoop RPC 源码阅读3
来源:互联网 发布:大数据maven 教程 编辑:程序博客网 时间:2024/05/16 09:17
DataNode要向NameNode发送请求,希望得到一个应答,Datanode是通过调用RPC类的getProxy方法在本地创建一个Namenode的代理,getProxy使用动态代理机制来创建一个指定服务端的代理。
下面分析ipc.RPC源码
ipc.RPC源码分析:
RPC中有一些内部类,除了前面提到的RPC.Server中之外,还有Invocation、ClientCache、Invoker等。
下面先看RPC的getProxy()方法:
/** Construct a client-side proxy object that implements the named protocol, * talking to a server at the named address. */ public static VersionedProtocol getProxy( Class<? extends VersionedProtocol> protocol, long clientVersion, InetSocketAddress addr, UserGroupInformation ticket, Configuration conf, SocketFactory factory, int rpcTimeout) throws IOException { if (UserGroupInformation.isSecurityEnabled()) { SaslRpcServer.init(conf); } VersionedProtocol proxy = // 通过Invoker类来 获取一个代理实例 (VersionedProtocol) Proxy.newProxyInstance( protocol.getClassLoader(), new Class[] { protocol }, new Invoker(protocol, addr, ticket, conf, factory, rpcTimeout)); long serverVersion = proxy.getProtocolVersion(protocol.getName(), clientVersion); if (serverVersion == clientVersion) { return proxy; } else { throw new VersionMismatch(protocol.getName(), clientVersion, serverVersion); } }
RPC的内部类Invoker类的继承自InvocationHandler,下面看一下Invoker.invoker()方法:
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { final boolean logDebug = LOG.isDebugEnabled(); long startTime = 0; if (logDebug) { startTime = System.currentTimeMillis(); } ObjectWritable value = (ObjectWritable) client.call(new Invocation(method, args), remoteId); // 将方法名和参数封装为一个Invocation对象传给client对象的call方法,获得服务器的返回结果值 if (logDebug) { // 这里,client的call会对这些请求参数做处理,发给服务器端,具体分析见前文ipc.Client的源码分析。 long callTime = System.currentTimeMillis() - startTime; LOG.debug("Call: " + method.getName() + " " + callTime); } return value.get(); }
以下是Hadoop RPC机制的一个剪影。
客户端调用NameNode的方法,就要获取NameNode的实例对象。
这样客户端首先调用RPC类中的getProxy方法,getProxy返回NameNode实例。
在getProxy中,首先RPC会生成一个Data对象data,给data设置方法名,函数名,
将当前的data传给Client,Client会与Server通信,获取一个完整的data。
与此同时,server端会调用RPC的getServer方法,要求启动Server实例,
Server实例启动后,收到Client发来的data,然后Server获取一个NameNode实例,
并将NameNode实例和data实例传递给Handler类,Handler通过反射机制设置Data,
Server与Client通信,将包含NameNode完整信息的实例data传给Client,由此getProxy方法获得NameNode实例
客户端获取NameNode实例,调用NameNode方法。
package Test;import NameNode.NameNode;import RPC.RPC;public class TestRpcClient {public static void main(String[] args) {for (int i = 0; i < 10; i++) { new Thread(new Runnable() { @Override public void run() { try { NameNode nameNode = RPC.getProxy(NameNode.class, "127.0.0.1", 8888); System.out.println(nameNode.doSomething1("我想做个代理!")); } catch (Exception e) { } } }).start();}}}
package RPC;import java.io.IOException;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.net.InetAddress;import java.net.ServerSocket;import java.net.Socket;import java.net.UnknownHostException;import server.Server;import Client.Client;import Data.Data;import NameNode.NameNode;public class RPC {//start a serverpublic static void getServer(NameNode nn, String host, int backlog, int port) throws UnknownHostException, IOException {ServerSocket ss = new ServerSocket(port, backlog, InetAddress.getByName(host));while (true) {Socket s = ss.accept();new Server(nn, s).start();}}//start a client connecting to the given serverpublic static NameNode getProxy(Class clazz, String host, int port) { Class[] interfaces = new Class[1]; interfaces[0] = clazz; return (NameNode) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), interfaces, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Data data = new Data(); data.setMethodName((String) method.getName()); data.setParaName((String) args[0]); return Client.processClient(data, "127.0.0.1", 8888).getReturnValue(); } });}}
package Client;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.net.Socket;import java.net.UnknownHostException;import Data.Data;public class Client {public static Data processClient(Data data, String host, int port) throws UnknownHostException, IOException, ClassNotFoundException { Socket socket = new Socket(host,port); //send a message to a given server ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream()); objectOutputStream.writeObject(data); objectOutputStream.flush(); //get message from server ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream()); data = (Data) objectInputStream.readObject(); //close connection objectOutputStream.close(); objectInputStream.close(); return data;}}
package Data;import java.io.Serializable;public class Data implements Serializable{public String getMethodName() {return methodName;}public void setMethodName(String methodName) {this.methodName = methodName;}public String getParaName() {return paraName;}public void setParaName(String paraName) {this.paraName = paraName;}public String getReturnValue() {return returnValue;}public void setReturnValue(String returnValue) {this.returnValue = returnValue;}private String methodName;private String paraName;private String returnValue;}
package Test;import NameNode.NameNodeImp;import RPC.RPC;public class TestRpcServer { public static void main(String[] args) throws Exception{ RPC.getServer(new NameNodeImp(), "127.0.0.1", 200,8888); }}
package server;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.net.ServerSocket;import java.net.Socket;import Data.Data;import NameNode.NameNode;import NameNode.NameNodeImp;public class Server extends Thread{private NameNode nn;private Socket socket; public Server(NameNode nn, Socket ss) {this.nn = nn;this.socket = ss;}public void run() {ObjectInputStream objectInputStream = null;try {objectInputStream = new ObjectInputStream(socket.getInputStream());Data data = (Data) objectInputStream.readObject();try {data = Handler.doMethod(nn, data);ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream()); objectOutputStream.writeObject(data); objectOutputStream.flush(); objectOutputStream.close(); objectInputStream.close();} catch (NoSuchMethodException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (SecurityException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalArgumentException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InvocationTargetException e) {// TODO Auto-generated catch blocke.printStackTrace();}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}}// apply java reflex private static class Handler {public static Data doMethod(NameNode nn, Data data) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {String methodName = data.getMethodName(); System.out.println(methodName);Class clazz = nn.getClass();Method m = clazz.getMethod(methodName, String.class);String result = (String) m.invoke(nn, data.getParaName());data.setReturnValue(result);return data;}}}
package NameNode;public interface NameNode {public String doSomething(String message) ;public String doSomething1(String message);}
package NameNode;public class NameNodeImp implements NameNode{@Overridepublic String doSomething(String message) {// TODO Auto-generated method stubreturn message+"Hello";}@Overridepublic String doSomething1(String message) {// TODO Auto-generated method stubreturn message+ "Hello2";}}
0 0
- Hadoop RPC 源码阅读3
- Hadoop RPC 源码阅读1
- Hadoop RPC 源码阅读2
- Hadoop RPC源码分析
- Hadoop RPC源码分析
- Hadoop源码学习:RPC
- Hadoop RPC 源码解析
- Hadoop RPC源码分析
- Hadoop RPC阅读笔记之一
- Hadoop源码之RPC机制
- Hadoop RPC机制+源码分析
- Hadoop 源码解析-rpc扩展
- [hadoop源码阅读][3]-新旧api区别
- Hadoop 源码阅读前奏
- Hadoop源码阅读2
- Hadoop源码阅读
- Hadoop源码阅读准备
- hadoop io 源码阅读
- 使用DOM解析XML(一)
- S3C6410移植u-boot-2013.01
- HTML5学习笔记简明版(3):新元素之hgroup,header,footer,address,nav
- android Http网络通信方式总结
- (关于编程实现数据的转换)说说 java与c语言的不同之处!!
- Hadoop RPC 源码阅读3
- HTML5学习笔记简明版(4):新元素之video,audio,meter,datalist,keygen,output
- 我常用到的hadoop命令
- HTML5学习笔记简明版(5):input的type超级类型
- Redis]windows下redis的安装和启动
- jquery.validate自定义规则
- HTML5学习笔记简明版(6):新增属性(1)
- 玩转CPU之直线
- 1023.EXCEL排序