美文网首页
Netty 学习笔记

Netty 学习笔记

作者: 瓢鳍小虾虎 | 来源:发表于2021-01-07 15:51 被阅读0次

Netty线程模型

Netty是一个基于NIO的高性能、高扩展性、事件驱动的网络应用程序框架,它极大的简化了TCP/UDP客户端和服务端的网络编程。Netty秉承了React设计思想。

Netty实现React模式的四个核心概念:
1)Resource:资源(请求/任务):主要指channel
2)Synchronous Event Demultiplexer:同步事件复用器:主要负责监听selector事件。
3)Dispatcher:分配器,主要负责网络io和事件分发
4)Request Handler:请求处理器,主要负责包装业务处理代码。

Netty源码中主要的对象:(这里只说个大致结构,重点在于思路,以后会补充源码解释。)

1)EventLoop:负责事件轮询,内部封装了selector,对事件的轮询本质就是对selector的轮询。EventLoop实际上不是一个,而是通过使用EventLoopGroup一下创建一组,数量默认值为硬件cpu数乘以2。根据react模型,会有2个线程组,一个是事件监听线程组,另一个是事件分发线程组。

2)Executor:负责线程管理,Executer负责线程的真正创建。EventLoop自身实现了executor接口,当调用executor方法提交任务的时候,首先会判断是否启动,未启动则调用内置的Executor创建线程并触发run方法执行。提交的任务的动作有时候会持续执行,EventLoop中有一个task quene,负责缓存。

3)channel:这里指的是netty自己封装的channel对象,内部除了有channel还有其他的元素,比如一个叫unsafe的对象,他负责io相关操作封装;还有pipeline,用于处理通道事件处理链路;再有eventLoop,保存当前的eventLoop,用于执行操作。

4)handler:负责具体业务处理

5)ServerBootstrap: 负责启动行为,把以上各种元素都给组织起来服务才能运转,可以理解是用了一种组合模式。

责任链设计模式

以上的内容主要是从事件驱动,事件分发的角度理解netty。
下面的内容主要关注具体任务的处理过程,用的是责任链设计模式。
责任链的数据结构可以理解为一个链表。

责任链设计主要的元素:

1)上下文对象:负责管理整个责任链,为handler提供往下执行的开关。责任链的操作实际上就是在操作上下文对象。
2)handler:负责承载具体业务实现。

零拷贝机制

Nio数据操作使用的是ByteBuffer这个工具类,日常开发过程中,开发人员发现jvm的ByteBuffer有一些缺陷:

1)无法动态扩容,当数据大于ByteBuffer容量会引发索引越界异常。

  1. api使用繁琐,比如flip(),rewind(),compact()等,使用稍有不慎就会出现错误。

因此netty为自己设计了一款ByteBuf,通过一系列骚操作,实现了支持动态扩容。并且实现了零拷贝机制,提高了io效率。

下面是netty的ByteBuf数据模型:


image.png

下面是一些ByteBuf操作实例:


image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png

注意虽然ByteBuf被清零,但是没有影响到指针。


image.png
image.png
image.png
在写入超过ByteBuf容量的时候,ByteBuf会自动扩容。
自动扩容的过程:

1)先判断待写区域是否够用,够用则不扩容。

2)如果待写区域不够用,则使用内部的工具类计算扩容大小。

  • 需要传2个参数,
    一个是最小容量(已读取大小 + 需要写入大小,即 3 + 11 = 14),
    一个是最大容量(int最大值,2G)。
    同时算法内部有一个阈值,默认大小为4m。
  • 如果最小容量等于阈值,则返回阈值。
  • 如果最小容量大于阈值,则 结果 = (最小容量 / 阈值) * 阈值 + 阈值。有点按比例扩容的意思。
  • 如果最小容量小于阈值,则使用一个初始值64,如果初始值小于最小容量,则翻倍再比较,以此类推。幂级扩容。

我们创建ByteBuf的容量如果不设置,默认是256字节,最大值为Integer.MAX_VALUE(2G)。

零拷贝机制原理:
netty的零拷贝是一种应用层面的优化,并不是jvm、操作系统层面有什么特别之处。
netty的零拷贝其实就是生成一个虚拟buffer,这个buffer存的不是其他buffer的副本,而是其他buffer的引用,原有的buffer不会受任何影响。

零拷贝的3种使用方式:包装,切割,组合


image.png
image.png

关于BIO、NIO、React模型:https://www.jianshu.com/writer#/notebooks/46113149/notes/81943681

相关文章

网友评论

      本文标题:Netty 学习笔记

      本文链接:https://www.haomeiwen.com/subject/wxuuoktx.html