TThreadedSelectorServer允许你用多个线程来处理网络I/O。它维护了两个线程池,一个用来处理网络I/O,另一个用来进行请求的处理
TThreadedSelectorServer模式是目前Thrift提供的最高级的模式,它内部有如果几个部分构成:
(1) 一个AcceptThread线程对象,专门用于处理监听socket上的新连接;
(2) 若干个SelectorThread对象专门用于处理业务socket的网络I/O操作,所有网络数据的读写均是有这些线程来完成;
(3) 一个负载均衡器SelectorThreadLoadBalancer对象,主要用于AcceptThread线程接收到一个新socket连接请求时,决定将这个新连接请求分配给哪个SelectorThread线程。
(4) 一个ExecutorService类型的工作线程池,在SelectorThread线程中,监听到有业务socket中有调用请求过来,则将请求读取之后,交个ExecutorService线程池中的线程完成此次调用的具体执行;
如上图所示,TThreadedSelectorServer模式中有一个专门的线程AcceptThread用于处理新连接请求,因此能够及时响应大量并发连接请求;另外它将网络I/O操作分散到多个SelectorThread线程中来完成,因此能够快速对网络I/O进行读写操作,能够很好地应对网络I/O较多的情况;TThreadedSelectorServer对于大部分应用场景性能都不会差,因此,如果实在不知道选择哪种工作模式,使用TThreadedSelectorServer就可以。
服务端代码:
private static void threadedSelectorServer() throws TTransportException {
TNonblockingServerTransport serverSocket=new TNonblockingServerSocket(8888);
TThreadedSelectorServer.Args serverParams=new TThreadedSelectorServer.Args(serverSocket);
serverParams.protocolFactory(new TBinaryProtocol.Factory());
serverParams.processor(new ISayHello.Processor<Iface>(new SayHelloImpl()));
TServer server=new TThreadedSelectorServer(serverParams); //简单的单线程服务模型,常用于测试
server.serve();
}
客户端代码:
private static void nonblockingSocket() throws Exception {
TTransport transport = new TFramedTransport(new TSocket("localhost", 8888));
TProtocol protocol = new TBinaryProtocol(transport);
ISayHello.Client client = new ISayHello.Client(protocol);
transport.open();
int i = 5;
while (i > 0) {
System.out.println("client调用返回:" + client.sayHello("张三"));
i--;
}
transport.close();
}
异步客户端代码:
private static void asyncClient() throws Exception {
TAsyncClientManager clientManager = new TAsyncClientManager();
TNonblockingTransport transport = new TNonblockingSocket("localhost", 8888);
Factory factory = new TBinaryProtocol.Factory();
ISayHello.AsyncClient asyncClient = new ISayHello.AsyncClient(factory, clientManager, transport);
System.out.println("Client calls .....");
MethodCallback callBack = new MethodCallback();
asyncClient.sayHello("李四", callBack);
Object res = callBack.getResult();
while (res == null) {
res = callBack.getResult();
}
System.out.println(((ISayHello.AsyncClient.sayHello_call) res).getResult());
}