[Hadoop RPC服务端:Server]
服务端的基本思路可以简述如下:通过网络获取到远程调用相关的信息,找到对应的方法,执行完成后,将结果通过网络发送给客户端。
对于服务端,我们将主要关心内部的实现机制,找到服务端处理一次远程调用的整个流程。
与Server相关的类主要为下面几个(都是Server的内部类)
Server.Listener &
Server.Listener.Reader
将Listener和Reader放在一起,主要是因为Listener和Reader在一起合作,使用Java NIO来实现的网络请求的监听和接收。简单说来,就是Listener线程负责监听来自客户端的socket连接请求,做accept请求操作。然后将建立连接的channel注册到Reader上,由Reader来负责处理数据到达的事件。这里主要使用基于Java NIO实现的网络事件的处理,因此需要对Java NIO有基本的了解,才能读懂这里的代码逻辑。
Server.Connection
代表一个客户端和服务端的连接的访问通道。每个连接到服务端的channel都有一个附加Connection对象,来作为业务上的连接。服务端每次在accept客户端的连接请求的时候,会创建一个Connection对象,将之绑定在这个channel上。
在Connection中会读取数据,将数据反序列化成对应的对象。
Server.Call
表示一次远程调用业务,包含了本次远程过程调用的一些请求参数信息,以及执行完过程调用之后的返回结果信息。
Server.Responder
Responder在server模型中,主要负责远程调用结果的返回,将远程调用的结果通过socket发送给对应的客户端。
Server.Handler
Handler主要负责任务调度。从Server的Call队列中消费远程调用业务,交给Responder返回给客户端。
1、Server的入口
Server的入口可以认为是两部分,一个是构造函数生成一个Server对象,一个是start方法启动Server服务
protected
Server(String bindAddress,
int
port,
Class<?
extends
Writable> rpcRequestClass,
int
handlerCount,
int
numReaders,
int
queueSizePerHandler, Configuration conf,
String serverName, SecretManager<?
extends
TokenIdentifier> secretManager,
String portRangeConfig)
throws
IOException {
this
.
bindAddress
= bindAddress;
this
.
conf
= conf;
this
.
portRangeConfig
= portRangeConfig;
this
.
port
= port;
this
.
rpcRequestClass
= rpcRequestClass;
this
.
handlerCount
= handlerCount;
this
.
socketSendBufferSize
= 0;
this
.
maxDataLength
= conf.getInt(CommonConfigurationKeys.
IPC_MAXIMUM_DATA_LENGTH
,
CommonConfigurationKeys.
IPC_MAXIMUM_DATA_LENGTH_DEFAULT
);
if
(queueSizePerHandler != -1) {
this
.
maxQueueSize
= queueSizePerHandler;
}
else
{
this
.
maxQueueSize
= handlerCount * conf.getInt(
CommonConfigurationKeys.
IPC_SERVER_HANDLER_QUEUE_SIZE_KEY
,
CommonConfigurationKeys.
IPC_SERVER_HANDLER_QUEUE_SIZE_DEFAULT
);
}
this
.
maxRespSize
= conf.getInt(
CommonConfigurationKeys.
IPC_SERVER_RPC_MAX_RESPONSE_SIZE_KEY
,
CommonConfigurationKeys.
IPC_SERVER_RPC_MAX_RESPONSE_SIZE_DEFAULT
);
if
(numReaders != -1) {
this
.
readThreads
= numReaders;
}
else
{
this
.
readThreads
= conf.getInt(
CommonConfigurationKeys.
IPC_SERVER_RPC_READ_THREADS_KEY
,
CommonConfigurationKeys.
IPC_SERVER_RPC_READ_THREADS_DEFAULT
);
}
this. callQueue = new LinkedBlockingQueue<Call>(maxQueueSize
);
this
.
maxIdleTime
= 2 * conf.getInt(
CommonConfigurationKeysPublic.
IPC_CLIENT_CONNECTION_MAXIDLETIME_KEY
,
CommonConfigurationKeysPublic.
IPC_CLIENT_CONNECTION_MAXIDLETIME_DEFAULT
);
this
.
maxConnectionsToNuke
= conf.getInt(
CommonConfigurationKeysPublic.
IPC_CLIENT_KILL_MAX_KEY
,
CommonConfigurationKeysPublic.
IPC_CLIENT_KILL_MAX_DEFAULT
);
this
.
thresholdIdleConnections
= conf.getInt(
C