netty源码

服务端创建步骤

步骤1.创建ServerBootstrap实例,ServerBootStrap是Netty服务端的启动辅助类,它提供了一系列的方法用于设置服务端启动的相关参数。底层通过门面模式对各种功能进行抽象和封装。ServerBootStrap只有一个无参的构造函数,是因为它的参数太多,而且未来会发生变化,所以引入了Builder模式。

步骤2.设置并绑定Reactor线程池-EventLoopGroup,负责处理所有注册到被线程多路复用器Selector上的Channel,Selector的轮询操作由绑定的EventLoop线程run方法驱动。

步骤3.设置并绑定服务端Channel。利用工厂类,通过反射创建NioServerSocketChannel对象。

步骤4.链路建立的时候创建并初始化ChannelPipeline。ChannelPipeline本质就是一个负责处理网络事件的职责链,负责管理和执行Channelhandler.网络事件以事件流的形式在ChannelPipeline中流转,根据ChannelHandler的执行策略调度ChannelHandler的执行-------采用策略模式和责任链模式。

步骤5。添加并设置Channelhandler.采用适配器模式,用户可以添加自己的实现,完成大多数的功能定制。----适配器模式。

步骤6:绑定并启动箭筒端口。

步骤7:Selector轮询。由Reactor线程NioEventLoop负责调度和执行Selector轮询操作,选择准备就绪的Channel集合。

步骤8:当轮询到准备就绪的Channel之后,就由Reactor线程执行ChannelHandler

ByteBuf源码精读

1.传统java的NIO的byteBuffer的缺点?

第一,ByteBuffer长度固定,一旦分配完成,它的容量不能动态扩展和收缩,当需要编码的POJO对象大于ByteBuffer的容量时,会发生索引越界异常;

第二,ByteBuffer只有一个标识位置的指针position,读写的时候需要手工调用flip()和rewind()等,使用者必须小心谨慎的处理这些API

第三,ByteBuffer的API功能有限,一些高级和实用的特性它不支持,需要使用者自己编程实现。

ByteBuf的实现原理图

ByteBuf对于内存的使用情况描述?

从内存分配的角度看,ByteBuf可以分为两类:

第一类,堆内存(HeapByteBuf)字节缓冲区:特点是内存的分配和回收速度快,可以被JVM自动回收;缺点是如果进行Socket的I/O读写,需要额外做一次内存复制,将堆内存对应的缓冲区复制到内核Channel中,性能会有一定程度的下降

第二类,直接内存(DirectByte)字节缓冲区:非堆内存,它在堆外进行内存分配,相比于堆内存,它的分配和回收速度会慢一些,但是将它写入或者读取时,由于少了一次内存复制,速度比堆内存块。

总结:在IO通信线程的读写缓冲区使用直接内存,后端业务消息的编解码模块使用HeapByteBuf。

从内存回收角度看,ByteBuf也可分为两类

第一类:基于对象池的ByteBuf,可以重用ByteBuf对象,它自己维护了一个内存池,可以循环利用创建的ByteBuf,提升内存的使用效率,降低由于高负载导致的频繁GC。但是内存池的管理和维护更加复杂,使用起来更加谨慎。

第二类:普通ByteBuf。

ByteBuf的动态扩容

动态扩展缓冲区的原理,是新建一个更大的缓冲区,把在原来缓冲区的内容复制到新的缓冲区,然后就有更大的空间可以写入了。中间涉及内存的分配和内存复制,所以扩容的成本较高。

 netty缓存扩容的策略一方面要让扩容能满足后面写入的需求,不能扩容之后,马上缓冲区又被填满,又需要再一次的扩容。另一方面不能一次性扩容太多,导致内存浪费。所以一般是先倍增,再步增,举个例子,原来缓存区1M,扩容到2M,再扩容到4M,再扩容到8M,如果再继续倍增,那扩容的内存就太多了,之后就采取每次扩容4M的方式,扩容到12M,再扩容到16M。

PooledByteBuf内存池原理

为了集中管理内存的分配和释放,同时提高分配和释放内存时候的性能,很多框架和应用都会通过预先申请一大块内存,然后通过提供的分配和释放接口来使用内存。这样一来,对内存的管理就被集中到几个类或者函数中,由于不再频繁使用系统调用来申请和释放内存,应用或者系统的性能也会大大提高。在这种设计思路下,预先申请的那一块内存就被成为Memmory Arena。

不同的框架,Memory Arena的实现不同,Netty的PoolArena是由多个chunk组成的大块内存区域,而每个chunk则由一个或者多个page组成,因此,对内存的组织和管理也就主要集中在如何管理和组织Chunk和Page上了。

Chunk主要用来组织和管理多个page的内存分配和释放,在Netty中,Chunk中的Page被构建成一颗二叉树。假设一个Chunk由16个page组成,name这些P啊啊个将会按照如下分布。

当一个节点被分配出去之后,这个节点就会被标记为已分配,自这个节点以下所有节点在后面的内存分配中被忽略,采用深度优先算法。

ChannelPipeline和ChannelHandler

这种机制类似于Servlet和Filter过滤器,这类拦截器实际上是职责链模式的一种变形,主要是为了方便时间的拦截和用户业务逻辑的定制。它将Channel的数据管道抽象为ChannelPipeline,消息在ChannelPipeline中流动和传递。ChannelPipeline持有IO事件拦截器ChannelHandler,由ChannelHandler对IO事件进行拦截和处理,可以方便得通过新增和删除ChannelHandler来实现不同业务逻辑定制。

EventLoop和EventLoopGroup

1.Reactor线程模型-单线程模型。

所有的IO操作都在同一个NIO线程上面完成。模型如下

2.Reactor线程模型-多线程模型,有一组NIO线程来处理IO操作。

多线程模型的特点:第一有专门一个NIO线程Accpetor线程用于监听服务端,接受客户端的TCP连接请求;第二读写由一个NIO线程池负责,线程池可以采用标准的JDK线程池实现;第三一个NIO线程可以同时处理N条链路,但是一个链路对应一个NIO线程。

主从Reactor多线程模型

主从Reactor多线程模式的特点:服务端用于就收客户端连接的不再是一个单独的NIO线程,而是一个单独的NIO线程池。Accptor接受到客户端TCP连接请求并处理完成后,将新创建的SocketChannel注册到IO线程池的某个IO线程上。Acceptor线程池仅仅用于客户端的登录,握手和安全认证,一旦链路建立成功,就将链路注册到后端subReactor线程池的IO线程上。

2.Netty的线程模型

Netty的线程模型并不是一成不变的,它实际取决于用户启动参数的配置。通过设置不同的启动参数,Netty可以同时支持Reactor单线程模型、多线程模型和主从Reactor多线程模型。

服务端启动的时候,创建了两个NioEventLoopGroup,他们实际上是两个独立的Reactor线程池,一个用于接受客户端的TCP连接,另一个用于处理IO相关的读写操作,或者执行系统Task、定时任务Task等。通过调整线程池个数、是否共享线程池等方式,Netty的Reactor线程模型可以在单线程、多线程和主从线程间切换。

3.NioEventLoop的主要任务

第一、负责IO的读写

第二、创建系统Task,通过调用NioEventLoop的execute方法实现,Netty有很多系统Task,创建他们的主要原因是:当IO线程和用户线程同时操作网络资源时,为了防止并发操作导致的锁竞争,将用户线程的操作封装成Task放入消息队列中,由IO线程负责执行,这样就实现了局部无锁化。

第二、定时任务。

Future和Promise

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,744评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,505评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,105评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,242评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,269评论 6 389
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,215评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,096评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,939评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,354评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,573评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,745评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,448评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,048评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,683评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,838评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,776评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,652评论 2 354

推荐阅读更多精彩内容