Tomcat NIO源代码分析(一) -- Acceptor
这里主要讲一下Tomcat使用NIO启动和进行请求处理的大致流程,使用的源码版本是7.0.5,对于其他处理等流程就不写了,我在别的文章里已经大致写过了,不过是用的6.0版本:http://zddava.iteye.com/category/53603。
当Tomcat配置成使用NIO时,启动过程其实和过去差不多,也是Connector#startInternal -> Protocol(Http11NioProtocol)#start() -> Endpoint(NioEndPoint)#start()的过程,这里主要看一下NioEndPoint:
这里先看一下init()方法,没有全列出来,最主要的一点就是初始化ServerSocketChannel:protected boolean setSocketOptions(SocketChannel socket) {// Process the connectiontry {// disable blocking, APR style, we are gonna be polling it// 这里终于看到了印象中的NIO的影子了socket.configureBlocking(false);Socket sock = socket.socket();socketProperties.setProperties(sock);// NioChannel是ByteChannel的子类// 从队列里取出第一个可用的Channel,这样的话NioChannel应该是设计成非GC的// 感觉其目的主要是对SocketChannel进行下封装NioChannel channel = nioChannels.poll();if (channel == null) {// 不过这里如果没有可用的就初始化一个的话请求数陡然增高再慢慢回落的时候不就浪费了内存了吗?// NioBufferHandler里分别分配了读缓冲区和写缓冲区// SSL setupif (sslContext != null) {SSLEngine engine = createSSLEngine();int appbufsize = engine.getSession().getApplicationBufferSize();NioBufferHandler bufhandler = new NioBufferHandler(Math.max(appbufsize,socketProperties.getAppReadBufSize()), Math.max(appbufsize,socketProperties.getAppWriteBufSize()), socketProperties.getDirectBuffer());channel = new SecureNioChannel(socket, engine, bufhandler, selectorPool);} else {// normal tcp setupNioBufferHandler bufhandler = new NioBufferHandler(socketProperties.getAppReadBufSize(),socketProperties.getAppWriteBufSize(), socketProperties.getDirectBuffer());channel = new NioChannel(socket, bufhandler);}} else {// 这里就是对Channel的重用了channel.setIOChannel(socket);if (channel instanceof SecureNioChannel) {SSLEngine engine = createSSLEngine();((SecureNioChannel) channel).reset(engine);} else {channel.reset();}}// 这里就是将SocketChannel注册到Poller了。// getPoller0用的循环的方式来返回Poller,即Poller 1, 2, 3... n 然后再回到1, 2, 3....getPoller0().register(channel);} catch (Throwable t) {ExceptionUtils.handleThrowable(t);try {log.error("", t);} catch (Throwable tt) {ExceptionUtils.handleThrowable(t);}// Tell to close the socketreturn false;}return true;}
好了,终于到了Poller了,下一篇开始Poller。