概述
RpcEngine
是ProtobufRpcEngine
和WritableRpcEngine
(已过时)的父类,在hadoop的RPC通讯的体系中扮演着很重要的角色
RpcEngine
的重要性在于,正常的RPC请求分为三个部分:通讯协议、Client端和Server端。通讯协议是Client和Server端沟通的桥梁
在Client是通过RpcEngine.getProxy
方法获取Server的代理对象;在Server端是通过getServer
方法获取Server端的实例。所以RpcEngine
是Hadoop RPC通讯体系中非常重要的父类定义
getServer:Server端获取RPC.Server的实例
getProxy:Client端获取RPC.Server的实例
getProtocolMetaInfoProxy:根据给定的connection id获取ProtocolMetaInfoPB代理对象
getServer解析
RpcEngine
只有一个getServer
方法获取RPC.Server的实例
/**
*
* 该方法用于产生一个RPC Server对象,服务器会启动这个Server对象监听从客户端发来的请求
* 成功从网络接收请求数据后,
* Server对象会调用Rpclnvoker(在RpcEngine的实现类中定义)对象处理这个请求
*
* Construct a server for a protocol implementation instance.
*
* @param protocol the class of protocol to use
* @param instance the instance of protocol whose methods will be called
* @param conf the configuration to use
* @param bindAddress the address to bind on to listen for connection
* @param port the port to listen for connections on
* @param numHandlers the number of method handler threads to run
* @param numReaders the number of reader threads to run
* @param queueSizePerHandler the size of the queue per hander thread
* @param verbose whether each call should be logged
* @param secretManager The secret manager to use to validate incoming requests.
* @param portRangeConfig A config parameter that can be used to restrict
* the range of ports used when port is 0 (an ephemeral port)
* @param alignmentContext provides server state info on client responses
* @return The Server instance
* @throws IOException on any error
*/
RPC.Server getServer(Class<?> protocol, Object instance, String bindAddress,
int port, int numHandlers, int numReaders,
int queueSizePerHandler, boolean verbose,
Configuration conf,
SecretManager<? extends TokenIdentifier> secretManager,
String portRangeConfig,
AlignmentContext alignmentContext) throws IOException;
getProxy解析
RpcEngine
有两个getProxy
方法获取ProtocolProxy
的实例
/**
* 客户端会调用RpcEngine.getProxy()方法获取一个本地接口的代理对象,
* 然后在这个代理对象上调用本地接口的方法
*
* getProxy()方法的实现采用了Java动态代理机制
*
* 客户端调用程序在代理对象上的调用会由一个
* RpcInvocationHandler(java.lang.reflect.InvocationHandler的子类,
* 在RpcEngine的实现类中定义)对象处理,
* 这个RpcInvocationHandler会将请求序列化(使用RpcEngine实现类定义的序列化方式)
* 并调用Client.call()方法将请求发送到远程服务器
*
* 当远程服务器发回响应信息后,RpcInvocationHandler会将响应信息反序列化并返回给调用程序,
* 这一切通过Java动态代理机制对于调用程序是完全透明的,就像本地调用一样
*
* @param protocol
* @param clientVersion
* @param addr
* @param ticket
* @param conf
* @param factory
* @param rpcTimeout
* @param connectionRetryPolicy
* @param <T>
* @return
* @throws IOException
*/
<T> ProtocolProxy<T> getProxy(Class<T> protocol,
long clientVersion, InetSocketAddress addr,
UserGroupInformation ticket, Configuration conf,
SocketFactory factory, int rpcTimeout,
RetryPolicy connectionRetryPolicy) throws IOException;
/** Construct a client-side proxy object. */
<T> ProtocolProxy<T> getProxy(Class<T> protocol,
long clientVersion, InetSocketAddress addr,
UserGroupInformation ticket, Configuration conf,
SocketFactory factory, int rpcTimeout,
RetryPolicy connectionRetryPolicy,
AtomicBoolean fallbackToSimpleAuth,
AlignmentContext alignmentContext) throws IOException;
代理类在程序运行时创建的代理方式被成为动态代理。 关于动态代理,代理类并不是在Java代码中定义的,而是在运行时根据我们在Java代码中的“指示”动态生成的。相比于静态代理, 动态代理的优势在于可以很方便的对代理类的函数进行统一的处理,而不用修改每个代理类中的方法
getProtocolMetaInfoProxy
根据给定的connection id
获取ProtocolMetaInfoPB
代理对象
/**
* Returns a proxy for ProtocolMetaInfoPB, which uses the given connection id.
* @param connId, ConnectionId to be used for the proxy.
* @param conf, Configuration.
* @param factory, Socket factory.
* @return Proxy object.
* @throws IOException
*/
ProtocolProxy<ProtocolMetaInfoPB> getProtocolMetaInfoProxy(
ConnectionId connId, Configuration conf, SocketFactory factory)
throws IOException;