Netty 4 源码分析——结构概览

鉴于Iteye上的人气越来越少,打算把上面的文章搬过来了。今天先搬Netty相关的。

下面是用excel画的一个简单的结构图

 

  • Channel是对最终I/O处理的封装
  • EventExecutor 封装了负责处理I/O 事件的线程
  • ChannelHandler 处理相关I/O Event的扩展接口,分为ChannelInboundHandler和[*]ChannelOutboundHandler,分别处理不同流向的事件
  • ChannelHandlerContext 对ChannelHandler相关信息的包装
  • ChannelPipeline 组装多个ChannelHandlerContext的管道,I/O事件在这个管道中流动
这里先简单描述下异步模式,就是在执行某个操作的时候,角色A通知角色B,我要执行某个操作,然后具体的执行由角色B去执行,角色B在执行操作的时候,角色A不会一直等到角色B的操作结果,而是继续执行自己的操作。角色B执行完后会将结果通知给角色A,角色A收到结果后再处理。 

     姑且给角色A取名命令者,角色B取名执行者。所以这里会有两个过程。一个是命令者通知执行者。一个是执行者通知命令者。在网络通信过程中这两个角色容易理解,命令者就是执行应用逻辑的线程,执行者是底层执行具体I/O的线程。 
     具体体现到类上的,EventExecutor就是I/O操作的执行者了,命令者通知执行者的过程描述是ChannelOutboundInvoker,而执行者通知命令者的过程描述就是ChannelInboundInvoker,这里的Inbound和Outbound是面向命令者来说的,而实际应用中的命令者就是应用逻辑了,netty本身作为一个框架肯定就是服务于应用的。对比ChannelOutboundInvoker和ChannelInboundInvoker中的方法名称,发现Inbound的中的都是firexxx,fire对通知是再形象不过的描述了。而Outbound中的都是xxx(ChannelPromise promise),命令口气十足啊,同时还给了执行者一个ChannelPromise,相当于告诉了执行者执行完后,把执行结果放到指定的地方,命令者在接收到执行者执行完成的通知后,就去前面指定的ChannelPromise中去取结果。 

ChannelPipeline描述的是命令者与执行者交互的过程,所以它既继承了ChannelInboundInvoker也继承了ChannelOutboundInvoker。 
ChannelHandlerContext是针对ChannelHandler的包装,处于ChannelPipeline中,所以它也同时实现了两个。 
Channel是负责与外部进行I/O的执行者的抽象,所以它继承了ChannelOutboundInvoker。 

     首先分析下Channel接口,接口文档中可以了解到:这个接口主要是封装了一些网络的I/O操作read,write,connect,bind。另外绑定了一下Channel相关的信息。ChannelConfig指定Channel的相关配置信息,ChannelPipeline负责命令者和执行者Channel之间的I/O事件传递。 
     有意思的是内部的UnSafe接口了,接口文档描述的是之所以取名UnSafe是因为不能从外部线程调用UnSafe接口中的方法,只能在Channel当前相关的I/O线程中调用。有一些接口除外,这个具体看下文档。UnSafe中才是真正的I/O操作实现,里面包含了register,bind,connect,disconnect,close,read,write,flush等操作,具体实现可以看子类了。 

这里先描述下具体I/O操作调用的流程, 
应用->Channel的I/O操作->调用Pipeline相应的I/O操作->调用ChannelHandlerContext的相应I/O操作->调用ChannelHandler的相应操作->Channel.UnSafe中相关的I/O操作。 
应用为什么不直接调用Channel.UnSafe接口中的I/O操作呢,而要绕一个大圈呢?因为它是框架,要支持扩展。 
执行者完成操作后,是如何通知命令者的呢?一般流程是这样的: 
Channel.UnSafe中执行相关的I/O操作,根据操作结果->调用ChannelPipeline中相应发fireXXXX()接口->调用ChannelHandlerContext中相应的fireXXXX()接口->调用ChannelHandler中相应方法->调用应用中的相关逻辑 

后面将按照上图中的各个元素逐一分析他们的源码。 


Netty5.0 架构剖析和源码解读 作者:李林锋 版权所有 email neu_lilinfeng@ © Netty5.0 架构剖析和源码解读1 1. 概述2 1.1. JAVA 的IO演进2 1.1.1. 传统BIO通信的弊端2 1.1.2. Linux 的网络IO模型简介4 1.1.3. IO复用技术介绍7 1.1.4. JAVA的异步IO8 1.1.5. 业界主流的NIO框架介绍10 2.NIO入门10 2.1. NIO服务端10 2.2. NIO客户端13 3.Netty源码分析16 3.1. 服务端创建16 3.1.1. 服务端启动辅助类ServerBootstrap16 3.1.2. NioServerSocketChannel 的注册21 3.1.3. 新的客户端接入25 3.2. 客户端创建28 3.2.1. 客户端连接辅助类Bootstrap28 3.2.2. 服务端返回ACK应答,客户端连接成功32 3.3. 读操作33 3.3.1. 异步读取消息33 3.4. 写操作39 3.4.1. 异步消息发送39 3.4.2. Flush操作42 4.Netty架构50 4.1. 逻辑架构50 5. 附录51 5.1. 作者简介51 5.2. 使用声明51 1. 概述 1.1.JAVA 的IO演进 1.1.1. 传统BIO通信的弊端 在JDK 1.4推出JAVANIO1.0之前,基于JAVA 的所有Socket通信都采用 BIO 了同步阻塞模式( ),这种一请求一应答的通信模型简化了上层的应用开发, 但是在可靠性和性能方面存在巨大的弊端。所以,在很长一段时间,大型的应 C C++ 用服务器都采用 或者 开发。当并发访问量增大、响应时间延迟变大后, 采用JAVABIO作为服务端的软件只有通过硬件不断的扩容来满足访问量的激 增,它大大增加了企业的成本,随着集群的膨胀,系统的可维护性也面临巨大 的挑战,解决这个问题已经刻不容缓。 首先,我们通过下面这幅图来看下采用BIO 的服务端通信模型:采用BIO 通信模型的 1connect NewThread1 WebBrowse 2connect 2handle(Req) WebBrowse 3connect Acceptor NewThread2 WebBrowse WebBrowse 4connect NewThread3 3sendResponsetopeer NewThread4 图1.1.1-1 BIO通信模型图 服务端,通常由一个独立的Accepto 线程负责监听客户端的连接,接收到客户 端连接之后为客户端连接创建一个新的线程处理请求消息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值