欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Netty源码分析 之 实现原理

程序员文章站 2022-06-08 18:50:19
...

开门见山,在此我就不介绍Netty,关于Neety的介绍、用法我在此推荐一篇文章http://www.kafka0102.com/2010/06/167.html,关于Java NIO网络编程的知识请Google。

 

Netty版本:3.6.6

 

个人觉得Netty之所以高性能主要是因为它的多路I/O复用模型和零拷贝的Buffer。

Netty中有两大核心组件ChannelFactory与ChannelPipeline,可以说Netty的整个架构的核心都是靠这两大组件支撑起来的。

 

Netty的网络模型(ChannelFactory)

 


Netty源码分析 之 实现原理
            
    
    博客分类: java Netty 

ChannelFactory有两组线程池BossPoolWorkerPoolBossPool相对上图的mainReactor负责接受连接请求,workerPool对应上图的SubReactorThreadPool部分,用于处理自身任务队列、读、写等操作。

BossPool工作线程接受到连接后,将此连接交给workerPoolworkerPool监听并处理此连接的读写事件.

下面看一下Netty的网络模型实现原理

ChannelFactory接口

它负责创建Channel

 

NioServerSocketChannelFactory

实现自ChannelFactory接口,服务器端的Channel工厂

 

NioClientSocketChannelFactory

实现自ChannelFactory接口,客户端的Channel工厂

这两个实现类中都维护了3个对象bossPoolworkerPoolsink;

sink:则对应PipeLine设计模式(下面会了解到)中的sink部分;

 

下面是ChannelFactory的基本原理图(有些类,有些方法看不懂没事,源码分析的时候会了解到)

 

Netty源码分析 之 实现原理
            
    
    博客分类: java Netty 

Thread Pipeline设计模式

 

关于此设计模式的思想请参看此PPThttp://febird.googlecode.com/svn-history/r515/trunk/febird/doc/multi_thread_pipeline_cn.pptx

这个PPT讲得可能有点抽象,我举个包子解释一下:

Pipeline可以看成是生产车间的一条生产流水线,原材料(数据)经过流水线中的每一道工序加工(也就是Handler)最终成为一个产品,每道工序由不同的人(Thread)干,有的工序复杂做得比较慢,有的工序简单做得比较快,但是一个产品必需等到所有工序都加工完后才能进行组装出厂(sink所干的事)。

 

WorkThreadPool:有了生产线流水线那谁来负责生产呢?工人。如果把工人看成是一个Thread那么一个生产车间里的所有工人组成的集合可以看成是ThreadPool。正常情况下,一个工人往往会被分配很多的原材料(数据),但一个工人每次只能加工一个原材料(假设是这样),因此必需要有一个池子(任务排队)来保证工人们正常完成工作,工人的工资一般与自己加工的产品量挂钩,如果大家都从这个池子里拿原材料加工将很有可能会导致冲突(线程同步导致的阻塞),因此厂里给每个工人按月给定一定的数量的任务(WorkThread有了自己的队列),这样每个工人各自完成各自的任务,几乎不会有竞争。

ChannelPipeline的默认实现类是DefaultChannelPipeline,各个被注册到Pipeline中的ChanelHandler都是在同一个工作线程中执行的,不会被拆分到多个线程中去,DefaultChannelPipeline中维护的是一个单向前后节点相连的链表的首尾指针(head,tail),此链表的数据结构如图:

 
Netty源码分析 之 实现原理
            
    
    博客分类: java Netty 

                                                          (DefaultChanelPipeline)

 

 

当底层NIO触发“读”事件的时候将从head节点开始执行如下动作:

1、判断当前节点的Handler是否实现了ChannelUpstreamHandler接口

             a)如果是则执行其handleUpstream(ctx, e)

             b)否则继续向查找next直到为next为null

 

当代码调用channel.write方法后将从tail节点开始执行如下动作:

1、判断当前节点的Handler是否实现了ChannelDownstreamHandler接口

             a)如果是则执行其handleDownstream(ctx, e)

             b)否则继续查找prev直到为prev为null

             c)当上面两种情况在执行的时候,如果当前节点的prev为null的时候则执行此Pipeline中sink对象的eventSunk方法做关闭、绑定、链接、写数据等操作

 如图

 
Netty源码分析 之 实现原理
            
    
    博客分类: java Netty 
 从图中可以看出底层NIO触发read事件将触发PipelineUpstream直到最后的Hhandler处理完成(这里通常做解码操作)后丢弃;当用户代码调用Channelwrite方法后将触发PipelineDownStream直到最前面的Handler处理完后(这里通常做编码操作)再执行底层Socketwrite操作。

自定义的ChannelHandler可以控制是否继续执行后续的handler。这点很像Spring中的ReflectiveMethodInvocation

 

  • Netty源码分析 之 实现原理
            
    
    博客分类: java Netty 
  • 大小: 80.5 KB
  • Netty源码分析 之 实现原理
            
    
    博客分类: java Netty 
  • 大小: 201.5 KB
  • Netty源码分析 之 实现原理
            
    
    博客分类: java Netty 
  • 大小: 7.6 KB
  • Netty源码分析 之 实现原理
            
    
    博客分类: java Netty 
  • 大小: 15.3 KB
相关标签: Netty