扫码关注公众号:芋道源码

发送: 百事可乐
获取永久解锁本站全部文章的链接

《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 http://ericcenblog.com/2017/12/01/jettyyuan-ma-pou-xi-xi-lie-4-connectorru-he-jie-shou-chu-li-wang-luo-qing-qiu/ 「Eric Cen」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注微信公众号:【芋道源码】有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

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

下回分解:)

文章目录