Jetty源码剖析系列(4)-Connector如何接收处理网络请求

书接上文,上文分析到ServerConnectordoStart方法会根据CPU的数量协调出一定数量的Acceptor,然后再把Acceptor交给线程池去执行: AbstractConnector.doStart(): Acceptor实现了Runnable接口,进去看它的run方法: 我们注意到它在while循环里面调用了accept方法,这个方法就是接收网络请求的入口了: 从上图的accept方法我们可以看到,它实际上就是调用了ServerSocketChannelaccept方法,我们终于回归到了NIO的基本,注意ServerSocketChannelaccept方法是阻塞的,直到接收到一个建立连接的请求,它就会返回一个SocketChannel,然后调用accepted方法,继续进入accepted方法看看: 先把SocketChannel设置为nonBlocking的,然后从SocketChannel里拿出Socket设置一些TCP属性: 比如会把该socket设置为TCP_NODELAY,这个是要disable Nagle's algorithm。设置完Socket后,就会调用SelectorManageraccept方法: 到这里,我们看到了ManagedSelector这个类,这个类是干嘛的呢?而SelectManager又是哪来的?我们回过头来看一下ServerConnector的构造方法: 可以看到_manager是在ServerConnector的构造方法里通过调用newSelectorManager方法得到的,而newSelectorManager方法里实际就是直接new出来: 再看回ServerConnector的构造方法里,_manager会被加进ServerConnectormanagedBean里面,在调用ServerConnectordoStart方法时,它的managedBean也会被启动(被调用start方法,进而调用它的doStart方法), 那我们就再进去看一下SelectorManagerdoStart方法: 它先是通过newSelector方法创建ManagedSelector,ManagedSelector数目是跟CPU数目协调出来的, 然后再把ManagedSelector加进SelectManagermanagedBean里面,同样在启动SelectManagerdoStart方法时,ManagedSelectordoStart方法也会被启动: ManagedSelectordoStart先通过SelectorManagernewSelector方法创建出一个Selector,这个selector就是Java NIO里面的Selector 然后SelectorManager会execute_strategyproduce方法(这里用的Java 8的语法),那么_strategy是啥呢?我们看回ManagedSelector的构造方法: 我们看到_strategyEatWhatYouKill?这是什么鬼?这个命名实在是有意思。我们暂且按下不表。我们看到_strategy同样会被加进ManagedSelectormanagedBean里面,那就代表启动ManagedSelector的时候,_strategydoStart方法也会被启动,而EatWhatYouKill并没有重写ContainerLifeCycledoStart方法,我们再看一下EatWhatYouKill的构造方法: 我们看到Producer被加进EatWhatYouKillmanagedBean里面了,那这个Producer又是什么鬼?我们再回到ManagedSelector的构造方法里: 我们看到ProducerSelectorProducer, 在前面ManagedSelector的doStart方法里, selectorManager执行EatWhaYouKillproduce方法: 我们再看EatWhatYouKilldoProduce方法: 可以看到实际调用的SelectorProduceproduce方法: 当我看到里面调用的select()方法时,真的有种“终于等到你,还好我没放弃”的感觉:) 到这里,我们可以看到无论怎么写,最终还是用到最基本的Java NIO。 我们再回头看SelectProducerproduce方法里调用的processSelected方法: 它从key里面拿出attachment,如果attachmentSelectable的,比如说是一个EndPoint的话,它就会调用该attachmentonSelected方法(这里有个强转型),在这里,我们的attachmentSocketChannelEndPoint,那我们看一下它的onSelected方法(从ChannelEndPoint继承而来): 它会根据selectkey的状态返回不同的Runnable Task, 分别有runCompleteWriteFillable, runFillablerunCompleteWrite三种, EatWhatYouKilldoProduce方法拿到这个Runnable Task后,将会执行它的run方法,比如runFillable的,它会调用FillInterestfillable方法: 可以看到它实际调用的是Callbacksucceeded方法。那这个Callback又是什么?

下回分解:)

comments powered by Disqus