聊聊Thrift(三) thrift 服务篇-TThreadPoolServer
上一篇文章列举了3中主要的服务端的模式,是我们工作中主要使用的模式,包括2种非阻塞的模式(TNonblockingServer ,TThreadedSelectorServer )和一种阻塞的模式(TThreadPoolServer ),本文深入这三种模式进行逐一讲解,先从TThreadPoolServer 开始深入。
TThreadPoolServer
Server which uses Java's built in ThreadPool management to spawn off a worker pool that
TThreadPoolServer是thrift提供的阻塞的服务端模式,启动一个线程池来处理并发的RPC请求。TThreadPoolServer继承TServer,继承关系见下:
class的structure见下:
通过以下构造函数创建,在构造函数中会创建工作线程池,用来executorService_用来处理RPC请求,根据args参数判断用户是否自己设置了线程池,如未设置,就根据传递进来的参数创建线程池,使用ThreadPoolExecutor创建
corePoolSize:5
maximumPoolSize:用户设置
keepAliveTime:60
unit:TimeUnit.SECONDS
workQueue:用户设置
构造函数:
public TThreadPoolServer(Args args) {
super(args);
stopTimeoutUnit = args.stopTimeoutUnit;
stopTimeoutVal = args.stopTimeoutVal;
executorService_ = args.executorService != null ?
args.executorService : createDefaultExecutorService(args);
}
创建线程池:
private static ExecutorService createDefaultExecutorService(Args args) {
SynchronousQueue<Runnable> executorQueue =
new SynchronousQueue<Runnable>();
return new ThreadPoolExecutor(args.minWorkerThreads,
args.maxWorkerThreads,
60,
TimeUnit.SECONDS,
executorQueue);
}
serve为服务端的监听socket,处理业务请求的方法,流程如下:
通过上图可以看到,属于一个典型的阻塞IO,使用了线程池提供处理用户请求的速度
accept用户连接:serverTransport_.accept()->acceptImpl()->ServerSocket.accept()
工作线程:
while (!stopped_) {
int failureCount = 0;
try {
TTransport client = serverTransport_.accept();
WorkerProcess wp = new WorkerProcess(client);
while(true) {
int rejections = 0;
try {
executorService_.execute(wp);
break;
} catch(RejectedExecutionException ex) {
LOGGER.warn("ExecutorService rejected client " + (++rejections) +
" times(s)", ex);
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
LOGGER.warn("Interrupted while waiting to place client on" +
" executor queue.");
Thread.currentThread().interrupt();
break;
}
}
}
} catch (TTransportException ttx) {
if (!stopped_) {
++failureCount;
LOGGER.warn("Transport error occurred during acceptance of message.", ttx);
}
}
}
根据设置好序列化反序列化以及传输协议,接受用户请求后提交给线程池执行,处理,调用如下代码段处理
processor.process(inputProtocol, outputProtocol)