【Netty系列_2】Netty线程模型与核心组件解析(上)

引言

说起Netty,可能很多开发者并没有使用经验,但是我敢说,在你使用的框架中,一定有他的身影,比如(RocketMQ,redisson,dubbo,motan,Elasticsearch......想了解更多使用Netty的项目? --> 戳这里 ), 在本文中,我们将以通俗易懂的方式,讲清楚每一个组件的职责和作用。



  • 因为Netty是基于Java中NIO的封装,其本质还是使用到了Java中的NIO,所以我们先来了解下NIO的几个组件Channel ,SelectorByteBuffer

1、Java NIO 三剑客 Channel ,SelectorByteBuffer

image.png

1.1、 Java NIO 的 Channel

  • 可以简单理解为一条连接(短连接 or 长连接),或者有人叫它通道,也没问题。

1.2、Selector选择器

  • 每一个连接在创建后将会注册(必须是实现了SelectableChannel的连接才可以注册到selector中)到某一个选择器(selector)上,然后轮询选择器上IO已经就绪的channel,将某批IO就绪的channel对应的selectKey (在注册时候就将某个channel与某个SelectedKey绑定的) 添加进selectedKeys这个set集合中去,后续轮询则是对该selectedKeys轮询,取出对应的selectedKey上的channel,然后读取channel的数据到byteBuffer中,接着我们可以从byteBuffer缓冲区读取数据,并进行业务处理。

1.3、ByteBuffer缓冲区

  • 本质上是一个内存块,既可以写入数据,也可以从中读取数据,其提供了三个重要的成员属性:capacity(容量)、position(读写位置)、limit(读写的限制)对于byteBuffer,我们点到为止,知道他是干什么的就行了,对其怎么使用以及api,我们暂时不做过多展开,因为这个类的使用还是有点复杂的,一两句话也很难解释清。

1.4、(补充说明) selector可以监听的事件类型

需要说明的是,在channel注册到selector时候,会传入一个参数即ops,代表这个选择器对哪些事件感兴趣 ,直白些就是:指定选择器要监控的IO事件类型包括:
(1)可读:SelectionKey.OP_READ

(2)可写:SelectionKey.OP_WRITE

(3)连接:SelectionKey.OP_CONNECT

(4)接收:SelectionKey.OP_ACCEPT

什么是IO事件呢?这个概念容易混淆,这里特别说明一下。这里的IO事件不是对通道的IO操作,而是通道的某个IO操作的一种就绪状态,表示通道具备完成某个IO操作的条件。比方说,某个SocketChannel通道,完成了和对端的握手连接,则处于“连接就绪”(OP_CONNECT)状态。再比方说,某个ServerSocketChannel服务器通道,监听到一个新连接的到来,则处于“接收就绪”(OP_ACCEPT)状态。还比方说,一个有数据可读的SocketChannel通道,处于“读就绪”(OP_READ)状态;一个等待写入数据的,处于“写就绪”(OP_WRITE)状态



在讲解各个组件之前,我们需要先了解Netty是怎么工作的,以及每个环节都干了什么。这样我们从整体上有了自己的认识后,再去了解其每一个节点上的组件,我想这样会更好一些。

2、Netty线程模型(让我们知道Netty是如何工作的)

对于在上篇文章中 【Netty系列_1】Netty简介与I/O&线程模型 介绍的三种Reactor线程模型,Netty可以说是都支持。下面我们主要看基于Reactor主从多线程模型 下的Netty线程模型(在实际开发中,也是这种模型更多一些)

2.2、基于Reactor主从多线程模型下的Netty工作示意图

image.png

2.3、父子通道说明和对上图的解释

2.3.1、父子通道说明

  • 在解释前,有必要说一下常用的两种Channel,即 ServerSocketChannel和SocketChannel

    ServerSocketChannel对应的socket描述符是连接监听类型。连接监听类型的socket描述符,一般放在服务器端,它负责接收客户端的套接字连接,在服务器端,一个“连接监听类型”的socket描述符可以接受(Accept)成千上万的传输类的socket描述符,而SocketChannel对应的socket描述符是传输数据类型。传输类的socket描述符负责传输数据。同一条TCP的Socket传输链路(即连接),在服务器和客户端,都分别会有一个与之相对应的数据传输类型的socket描述符 这也是为什么ServerSocketChannel只在启动时创建一次,而SocketChannel则是新来个连接,就需要新建一个SocketChannel(在做Netty调优时候,我们有一招就是扩大系统(例如Linux)的文件描述符数量,其实这里的文件描述符,就是传输类型的文件描述符)

    在Netty中,将有接收关系的ServerSocketChannel和SocketChannel,叫作父子通道。其中,NioServerSocketChannel负责服务器连接监听和接收,也叫父通道(Parent Channel)。而NioSocketChannel传输类通道,叫做子通道(Child Channel)

2.3.2、对上图的解释(重要)

  1. boss group 用于监听客户端连接,如果轮询到父通道(ServerSocketChannel)中有接收就绪accept类的IO 事件,那么将会添加该父通道所绑定的selectKey到selectedKeys中,并通过while循环对selectedKeys进行轮询,只要selectedKeys有元素,那么就调用processSelectedKeys方法,之后将其添加到taskQueue队列,然后执行runAllTasks 并创建子通道(SocketChannel)并且将创建好的SocketChannel传递并注册到worker group的某个NioEventLoopselector中&#x
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值