Netty系列:Netty架构及分析
Posted jsnr-tdyd
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Netty系列:Netty架构及分析相关的知识,希望对你有一定的参考价值。
Netty作为高性能的网络通信框架,是每个java coder必学的一门技术,下面就通过画图的方式分析下Netty架构及启动和读写流程
一、架构
二、流程解析
1、启动流程
(1)服务端创建2个NioEventLoopGroup实例,分别是:BossGroup、WorkerGroup,并初始化NioEventLoopGroup实例中都维护NioEventLoop数组中的每个实例。备注:NioEventLoop会绑定一个线程,怎么绑定的呢?NioEventLoop有一个Thread成员变量,他表示的就是当前的执行线程,并且在运行过程中会判断是否在这个Thread成员变量是否为当前线程,如果是就将队列提交到队列,等待这个线程从队列中取出并消费,所以NioEventLoop里的任务队列也是单线程消费的
(2)通过启动引导类ServerBootstrap进行初始化和将Channel注册到Selector上
2.1、初始化:将bossGroup的ChannelHandler添加到NioserverSocketChannel对应的ChannelPipeline中, 这里的ChannelHandler
包含:Channelinitializer、LoggingHandler、ServerBootstrapAccetor, 在ChannelPipeline中是通过双向链表的方式维护ChannelHandler集合,ChannelHandler并不是直接添加到ChannelPipeline中,而是将ChannelHandler与之对应ChannelHandlerContext对象添加 ChannelPipeline中,通过持有ChannelHandlerContext的引用可以访 问ChannelHandler。所以,ChannelHandlerContext是连接ChannelHandler与ChannelPipeline之间的桥梁和纽带
2.2、注册:将NioServerSocketChannel注册到NioEventLoop维护Selector中
(3)Channel被注册到Selector上之后,就会在本地监听指定的端口
二、接收客户端连接
(4)在NioEventLoop#run方法里,通过死循环的方式不断检测是否有客户端连接进来,一旦有连接进来循环调用ChannelPipeline中
Handler的channelRead方法,channelRead方法他有2个参数,一个是ChannelHandlerContext, 另一个就是Object类型,实际上
他是NioSocketChannel类型,通过调用ServerBootstrapAcceptor的channelRead方法把NioSocketChannel交给
ServerBootstrapAcceptor,BossGroup只接受连接,真正处理执行操作的WorkerGroup,那么BossGroup接收到连接之后怎么把连接
(也就是Channel)交给WorkerGroup呢? 毫无疑问就是通过ServerBootstrapAcceptor进行连接的传递
(5)WorkerGroup拿到ServerBootstapAcceptor传递过来的Channel对象,WorkerGroup从自己维护的NioEventLoop数组里通过轮询
的方式选择其中一个NioEventLoop,并把Channel注册到NioEventLoop中的Selector上,完成通道的注册。
备注:由于NioEventLoop背后是有且只有一个线程处理的,是单线程模型,而一个Channel上的数据所有操作都是由这一个线程处理的,所以
在连接很多的情况下,一个NioEventLoop是需要处理多个Channel的,所以不能让这个单线程处理耗时的操作,否则它会阻塞与之相关的
所有Channel的操作,严重性能系统的性能,一般这些操作都是放到异步线程池里去做,目的就是为了与NioEventLoop中的单线程隔离开
三、等待客户端数据写入
(6)到此,客户端的连接Channel已经被注册到其中某一个NioEventLoop中的Selector上了,NioEventLoop在run方法里,死循环的方式检测通道是否准备就绪,一旦通过准备就绪就进行相应的处理
以上是关于Netty系列:Netty架构及分析的主要内容,如果未能解决你的问题,请参考以下文章