netty3 源码分析解

netty是一款开源的基于nio的通讯框架,参照tomcat源码,对比俩者的不同点,主要是基于nio和bio模式的分析。

下载netty3.7源码,导入eclipse,得到工程。netty基于Reactor设计模式的多路复用异步模式, 相对于传统的Bio,架构图如下:

netty3 源码分析解_第1张图片

select 模式netty抽象出来为boss, 每个channel netty分别用work 去处理,默认的work为2*(cpu*core)。 默认情况下boss为一个线程,这点跟tomcat一样,tomcat的bio为Acceptor处理模式。


首先netty是基于



打开EchoServer 如图

netty3 源码分析解_第2张图片


整体结构比较清晰, 代码也比较简单, ServerBootstrap是netty的启动入口, 初始化NioServerSocketChannelFactory类,此类主要是启动netty的Boss 和work线程。

同时Channels.pipeline(new EchoServerHandler()) , channelpipeline绑定自定义的EchoServerHandler. 打开这个类


netty3 源码分析解_第3张图片

发现很简单,主要是实现了消息接收方法,此方法明显是回调模式。

EchoServer看完了,我们首先进入到ServerBootstrap, EchoServer里面简单的设置了ServerBooStrap的工厂为NioServerSocketChannelFactory。 这个不多说,简单的工厂模式,通过工厂生产boss和work。

进入NioServerSocketChannelFactory 这个类, 

netty3 源码分析解_第4张图片


构造器依次调用,主要是为了生产出work 工作池和boss池,通过构造器顺序,得知首先生产work。


netty3 源码分析解_第5张图片netty3 源码分析解_第6张图片


然后生产boss对象池。进入NioWorkerPool,  

构造器里提供了俩个方法,调用父类构造器, init方法。 进入super()方法。

netty3 源码分析解_第7张图片

初始化workes 数组, autoInit = false;

进入init()方法

netty3 源码分析解_第8张图片

new了一组work线程。 进入newWork方法。

初始化nioWork传入线程池对象,进入


进入了nioSelector类,第一初始化executor, openSelector(determiner) 打开select选择器。

netty3 源码分析解_第9张图片


调用DeadLockProofWorker 类的start方法,这个类主要是为了异步启动niowork线程用的,进入。


netty3 源码分析解_第10张图片


调用了runnable.run方法,此时的runnable为newThreadRenamingRunnable, 再进一步进入,传入的runnable为this指针。逐级往上查看,this实际指向的是nioWork类。


netty3 源码分析解_第11张图片netty3 源码分析解_第12张图片



实际调用的是run方法。最终调用的是niowork.run方法

netty3 源码分析解_第13张图片



下面就是揭开面目了,实际上是简单的对select选择器进行了一次封装, 里面有select(selector方法), 点击进入。

netty3 源码分析解_第14张图片


再次回到abstractNioSelector.run方法,继续往下读。


AbstractNioSelector


netty3 源码分析解_第15张图片

下面进行process方法, process方法实际上是调用了AbstractNioWorker.process()方法, 如图


netty3 源码分析解_第16张图片

迭代select 判断事件类型,如果是可读状态, 则进行读操作,如果是可写状态则进行写操作, 进入read方法,传入selectKey.

netty3 源码分析解_第17张图片


读取io流结束,调用fireMessageReceived()方法,这个方法怎么感觉在哪见过, 是的,这个肯定是个回调方法, 打开EchoServerHandler

netty3 源码分析解_第18张图片

发现也有个xxReceived方法,没错,这里就是回调了我们这个方法。 回到上面去,



进入fireMessageReceived 方法在这里声明的,channel.getPipeline()这个方法貌似我们也在哪里定义过, 再回到EchoServer 


netty3 源码分析解_第19张图片


netty3 源码分析解_第20张图片


实际盛pipeline我们传入了我们的handler,此时就是通过这里关联起来的, 回到上一步。

channel.getPipeline().sendUpstream 进入


netty3 源码分析解_第21张图片



通过context上下午,得到我们之前的echoServerhandler 然后调用upstrean 事件冒泡, 点击方法,进如,如下

最终就到了我们的这个类的方法,



这个read过程就是这样。 

你可能感兴趣的:(netty3 源码分析解)