内部类Connection是一个线程类,提供建立Client到Server的Socket连接,发送RPC请求以及读取RPC响应信息等功能。Client与每个Server之间维护一个通信连接,与该连接相关的基本信息及操作被封装到Connection类中,基本信息主要包括通信连接唯一标识(remoteId)、与Server端通信的Socket(socket)、网络输入数据流(in)、网络输出数据流(out)、保存RPC请求的哈希表(calls)等。
Call类封装了一个RPC请求,它包含5个成员变量,分别是唯一标识id、函数调用信息param、函数执行返回值value、出错或者异常信息error和执行完成标识符done。由于Hadoop RPC Server采用异步方式处理客户端请求,这使远程过程调用的发生顺序与结果返回顺序无直接关系,而Client端正是通过id识别不同的函数调用的。当客户端向服务器端发送请求时,只需填充id和param两个变量,而剩下的3个变量(value、error和done)则由服务器端根据函数执行情况填充。
3.3、Server类的实现为了提高性能,Server类采用了很多技术提高并发能力,包括线程池,javaNIO提供的Reactor模式等。为了更好的理解Server类的设计,我们一步一步的推进:
3.3.1、Reactor模式RPC服务端的处理流程和所有网络程序服务端处理的流程类似:1、读取请求;2、反序列化请求;3、处理请求;4、序列化响应;5、发回响应。
Reactor模式是一种广泛应用在服务器端的设计模式,也是一种基于事件驱动的设计模式;Reactor的处理流程是:应用程序向一个中间人注册IO事件,当中间人监听到这个IO时间发生后,会通知并唤醒应用程序处理这个事件,这里所说的中间人其实是一个不断等待和循环的线程,它接收所以的应用程序的注册,并肩擦应用程序注册的IO事件是否就绪,如果就绪了则通知应用程序进行处理。
一个简单的基于Reactor模式的网络服务器设计如下图所示:主要包括reactor、acceptor以及hadndler等模块,其中reactor负责监听所有的IO事件,当检测到一个新的IO事件发生时,reactor就睡唤醒这个事件对应的模块处理。acceptor负责响应socket连接请求事件,会接收请求建立连接,之后构造handler对象,handler负责向reactor注册IO读事件,然后进行对应的业务逻辑处理,最后发回响应。
主要的步骤如下:
客户端发送socket连接请求到服务端,服务端的reactor对象监听到了这个IO请求,由于acceptor对象在reactor对象上注册了socket连接请求的iO事件,所以reactor会出发acceptor对象响应socket连接请求。
acceptor对象会接收到来自客户端的socket连接请求,并为这个连接创建一个handler对象,handler对象的构造方法在reactor对象上注册IO读事件。
客户端建立连接后,会通过socket发送RPC请求,RPC请求达到reactor后,会有reactor对象分发到对应的handler对象处理。
handler对象会从网络上读取RPC请求,然后反序列化请求并执行请求对应的逻辑,最后将响应信息序列化并通过socket发回给客户端。
由于上述的设计中服务端只有一个线程,所以就要求handler中读取请求、执行请求以及发送响应的流程必须能够迅速处理完成,如果在一个环节中发生了阻塞,则整个服务器逻辑全部阻塞。所以接下来看多线程的Reactor模式的网络服务器结构。
3.3.2、多线程的Reactor模式
在基础的Reactor模式的基础上,把占用时间比较长的读取请求部分也业务逻辑处理部分进行分开,交给两个独立的线程池处理,分别为readers的线程池和handler的线程池。readers线程池中包含若干个执行读取RPC请求任务的Reader线程。它们会在Reactor上注册读取RPC请求IO事件,然后从网络中读取RPC请求,并将RPC请求封装在一个Call对象中,最后将Call对象放入共享消息队列MQ中。而handers线程池包含很多个handler线程,它们会不断的从共享消息队列MQ中取出RPC请求,然后执行业务逻辑并向客户端发送响应。这样就保证了IO事件的监听和分发,RPC请求的读取和响应是在不同的线程中执行,大大提高了服务器的并发性能。具体的架构图如下:
上图就是多线程的Reactor模式版本,IO事件的监听、RPC请求的读取和处理就可以并发的进行了,但是像hadoop的Namenode这样的对象,同一时间会存在很多个socket连接请求以及RPC请求的道道,这样就会造成Reactor在处理和分发这些IO事件时出现阻塞,导致服务器性能下降,在这个的基础上可以拓展为多个reactor的模式。
3.3.3、多个Reactor多线程模式多个Reactor多线程模式结构如下图所示: