1.2.2 Netty框架源码学习

目录

2.2.1 netty线程模型

2.2.2 责任链设计模式

1、设计模式-责任链模式

2、责任链的4个要素

3、Netty中的ChannelPipeline责任链

4、入站事件

5、出站事件

6、Netty中事件的定义

7、Pipeline中的handler是什么

8、维护Pipeline中的handler

9、handler的执行分析

10、分析registered入站事件的处理

11、分析bind出站事件的处理

12、分析accept入站事件的处理

13、分析read入站事件的处理

2.2.3 零拷贝机制


2.2.1 netty线程模型

1、Netty异步事件驱动、网络应用程序框架
             netty是一个高性能、高可扩展性的异步事件驱动的网络应用程序框架,
            它极大地简化了TCP和UDP、客户端和服务器开发等网络编程
2、Netty的4个内容:
    Reactor线程模型:一种高性能的多线程程序设计思路
    Netty中自定义了Channel概念:增强版的通道概念
    ChannelPipeline职责链设计模式:事件处理机制
    内存管理:增强的ByteBuf缓冲区
3、Netty实现了Reactor线程模型
    4个核心概念:
        Resources资源(请求/任务)
        Synchronous Event Demultiplexer同步事件复用器
        Dispatcher分配器
        Request Handler请求处理器
4、带中文注释的netty源码地址https://github.com/crazyFeng/netty/tree/netty-4.1.32.final-remark
    克隆netty-4.1.32.final-remark分支

    NioEventLoop:将通道注册到EventLoop的selector上,进行事件轮询
        eventLoop实现了Excutor接口

5、netty源码查看:

    EventLoopGroup初始化过程

    EventLoop的启动

    bind绑定端口过程

6、Channel概念:
        netty中的Channel是一个抽象的概念,可以理解为对JDK NIO Channel的增强和拓展
        增加了很多属性和方法,完整信息可以看代码注释

7、Netty线程模型

8、Pipeline:从数据结构的角度,它是一个双向链表
          从逻辑的角度,它是netty的逻辑处理链
9、Pipeline的链表上有两种handler,Inbound Handler和Outbound handler
10、Head -> Tail (Inbound),Tail -> Head (Outbound)
11、ChannelPipeline仅仅只是逻辑处理的流程,真正逻辑处理器则是ChannelHandlerInvoker。
12、Channel以及Pipeline的处理流程:
    Channel.write -> ChannelPipeline.write -> ChannelHandlerContext.write -> ChannelHandlerInvoker.write -> ChannelHandler.write
13、netty精华文章推荐地址:http://www.52im.net/thread-98-1-1.html

2.2.2 责任链设计模式

1、设计模式-责任链模式

    责任链模式(Chain of Responsibility Pattern)为请求创建了一个处理对象的链
    发起请求和具体处理请求的过程进行解耦:
        职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,
        无须关心请求的处理细节和请求的传递

例如下图:发起了一个“做月饼”的请求,分工给多个handler做

2、责任链的4个要素

3、Netty中的ChannelPipeline责任链

4、入站事件

    通常指I/O线程生成了入站数据
    (通俗理解:从socket底层自己往上冒上来的事件都是入站)
    比如EventLoop收到selector的OP_READ事件,入站处理器调用socketChannel.read(ByteBuffer)
    接收到数据后,这将导致通道的ChannelPipeline中包含的下一个中的channelRead方法被调用

5、出站事件

    经常是指I/O线程执行实际的输出操作
    (通俗理解:想主动往socket底层操作的事件的都是出站)
    比如bind方法用意是请求server socket绑定到给定的SocketAddress,这将导致通道的
    ChannelPipeline中包含的下一个出站处理器中的bind方法被调用

6、Netty中事件的定义

7、Pipeline中的handler是什么

    ChannelHandler:用于处理I/O事件或拦截I/O操作,
                    并转发到ChannelPipeline中的下一个处理器
        这个顶级接口定义功能很弱,实际使用时会去实现下面两大子接口:
            处理入站I/O事件的ChannelInboundHandler、
            处理出站I/O操作的ChannelOutboundHandler
    适配器类:为了开发方便,避免所有handler去实现一遍接口方法,Netty提供了简单的实现类:
        ChannelInboundHandlerAdapter处理入站I/O事件
        ChannelOutboundHandlerAdapter来处理出站I/O事件
        ChannelDuplexHandler来支持同时处理入站和出站事件
    ChannelHandlerContext:实际存储在Pipeline中的对象并非ChannelHandler,而是上下文对象。
        将handler,包裹在上下文对象中,通过上下文对象与它所属的ChannelPipeline交互,
        向上或向下传递事件,或者修改pipeline都是通过上下文对象

8、维护Pipeline中的handler

    ChannelPipeline是线程安全的,ChannelHandler可以在任何时候添加或删除
    例如:可以在即将交换敏感信息是插入加密处理程序,并在交换后删除它。
    一般操作,初始化的时候增加进去,较少删除。
    下面是Pipeline中管理handler的API

9、handler的执行分析

10、分析registered入站事件的处理

11、分析bind出站事件的处理

12、分析accept入站事件的处理

13、分析read入站事件的处理

2.2.3 零拷贝机制

 

1、Netty自己的ByteBuf
    ByteBuf是为解决ByteBuffer的问题满足网络应用程序开发人员的日常需求而设计的
JDK ByteBuffer的缺点
    无法动态扩容
        长度是固定,不能动态扩展和收缩,当数据大于ByteBuffer容量时,会发生索引越界异常
    API使用复杂
        读写的时候需要手工调用flip()和rewind()等方法,使用时需要非常谨慎,否则很容易出错

2、ByteBuf的4个增强
        API操作便捷性
        动态扩容
        多种ByteBuf实现
        高效的零拷贝机制

3、ByteBuf的三个重要属性capacity(容量)、readerIndex(读取位置)、writerIndex(写入位置)
       提供两个指针(readerIndex、writerIndex)变量来支持顺序读和写操作
    常用方法定义
        getByte //随机访问索引
        read* //顺序读
        write* //顺序写
        discardReadBytes //清除已读内容
        clear //清除缓冲区
        搜索操作
        标记和重置
        引用计数和释放

4、ByteBuf的一个缓存区被两个指针分割成三个区域

5、ByteBuf动态扩容
    capacity默认值=256字节,capacity最大值=Integer.MAX_VALUE//2GB
    write*方法调用时,通过AbstractByteBuf的ensureWritable0方法进行检查
    容量计算方法:AbstractByteBufAllocator.calculateNewCapacity(新容量的最小要求,容量最大值)
                    根据新容量的最小值要求,对应有两套计算方法:
                        没超过4兆从64字节开始,每次增加一倍,直至计算出来的newCapacity满足新容量最小要求
                               eg:当前大小256,已写250,继续写10字节数据,需要的容量最小要求是261,则新容量是64*2*2*2=512
                        超过4兆新容量=新容量最小要求/4兆*4兆+4兆
                             eg:当前大小3兆,已写3兆,继续写2兆数据,需要的容量最小要求是5兆,则新容量是9兆(不能超过最大值2GB)

6、ByteBuf的8种具体实现

7、Unsafe的实现
    unsafe意味着不安全的操作,但是更底层的操作会带来性能提升和特殊功能,Netty中会尽力使用unsafe
    Java语言很重要的特性是"一处编写到处运行",所以它针对底层的内存或者其他操作,做了很多封装
    而unsafe提供了一系列我们操作底层的方法,可能会导致不兼容或者不可知的异常

Unsafe提供的一些方法

8、PooledByteBuf对象、内存复用

9、零拷贝机制

Netty的零拷贝机制,是一种应用层的实现,和底层JVM、操作系统内存机制并无过多关联

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值