【图解IO与Netty系列】Netty核心组件解析

news2024/11/13 14:09:15

Netty核心组件解析

  • Bootstrap & ServerBootstrap
  • EventLoop & EventLoopGroup
  • Channel
  • ChannelHandler & ChannelPipeline & ChannelHandlerContext
    • ChannelHandler
    • ChannelPipeline
    • ChannelHandlerContext
  • ChannelFuture

Bootstrap & ServerBootstrap

Bootstrap和ServerBootstrap是Netty应用程序的启动引导器,通过它可以配置我们的Netty应用程序并启动。其中Bootstrap是Netty客户端使用的启动引导器,而ServerBootstrap则是Netty服务端使用的启动引导器。

EventLoop & EventLoopGroup

EventLoop是事件循环,也是就我们在NIO程序中while循环调用Selector的select()方法进行监听然后处理就绪事件的逻辑,现在Netty通过EventLoop封装事件循环,使得我们无需重复编写事件循环的代码,只需要专注于就绪事件的处理逻辑。

每个EventLoop都对应一个线程,每个EventLoop又属于某个EventLoopGroup,因此EventLoopGroup相当于是线程组。我们常用的是NioEventLoopGroup,NioEventLoopGroup内部包含了一个或多个NioEventLoop,由我们的参数进行设置。

在这里插入图片描述

一个NioEventLoop内部包含一个Selector和一个Queue<Runnable>类型的taskQueue。

在这里插入图片描述

Selector就是NIO中的Selector,Selector是一个多路复用器,我们可以往Selector注册多个Channel,Selector可以帮我们监听注册在其上的Channel,当我们调用Selector的select()方法时,当前线程就阻塞,通过Selector监听注册在其上的Channel,等待关注的事件就绪。

在这里插入图片描述

于是,NioEventLoop内部线程的事件循环,就通过Selector的select()方法监听注册到Selector上的Channel,等待一个或多个Channel有关注的事件就绪。

当有事件就绪时,NioEventLoop内部线程会调用processSelectedKeys()方法处理就绪事件对应的Channel。

当processSelectedKeys()方法调用完毕后,NioEventLoop还会调用runAllTasks()方法处理被提交到自己的taskQueue中的异步任务。一些比较耗时但是实时性不高的任务,我们可以把它提交到NioEventLoop的taskQueue中让它异步处理。

当taskQueue中的任务处理完,一个事件循环就结束,进入下一次循环。

在这里插入图片描述

Channel

这里的Channel和NIO的Channel不是同一个东西,这里的Channel是Netty对NIO的Channel经过封装后的属于Netty自己的Channel。比如NIO中的ServerSocketChannel和SocketChannel,Netty把它们封装成了NioServerSocketChannel和NioSocketChannel。

在这里插入图片描述

除了持有NIO的Channel以外,还保存了各自关注的事件类型,等真正把NIO的Channel注册到Selector上的时候,就可以直接设置对应的事件类型。NioServerSocketChannel保存的是连接就绪事件OP_ACCEPT,而NioSocketChannel保存的是读就绪事件OP_READ。

在这里插入图片描述

在使用Java原生的NIO时,我们都会设置Channel为非阻塞的,也就是调用configureBlocking(false)方法,这里Netty自动帮我们设置为非阻塞了,无需我们手动设置。比如NioServerSocketChannel在构造方法中就调用了ServerSocketChannel的configureBlocking(false)方法。

在这里插入图片描述

除了NioServerSocketChannel和NioSocketChannel以外,Netty还有其他类型的Channel,比如BIO类型的Channel、UDP协议的Channel,这里就不列举了。

然后Netty中的每个Channel,都有对应ChannelPipeline用来处理Channel中就绪的事件。

在这里插入图片描述

ChannelHandler & ChannelPipeline & ChannelHandlerContext

与Chandler相关的其他组件包括ChannelHandler、ChannelPipeline、ChannelHandlerContext。每个Chandler都会有一个ChandlerPipeline与之对应,用于处理该Chandler上发生的事件,而ChandlerPipeline又会通过它内部的ChandlerHandler去处理到来的事件。

ChannelHandler

ChannelHandler是专门用于处理就绪事件的,我们在开发Netty应用程序时,主要就是编写各种ChannelHandler,在ChannelHandler中各种事件触发的方法中实现自己的处理逻辑。

ChannelHandler又分为是处理入站事件还是出站事件的。所谓入站事件,就是由于接收到外部的数据或消息等而触发的事件就是入站事件,比如读就绪事件就是入站事件,因为有数据到达才会触发读就绪事件;而出站事件则与入站事件相反,由自己主动触发的,流动方向是向外的事件就是出站事件,比如写就绪事件。

在这里插入图片描述

如果要编写处理入站事件的ChannelHandler,我们可以实现ChannelInboundHandler接口,ChannelInboundHandler就是专门用于处理入站事件的;如果要编写处理出站事件的ChannelHandler,我们可以实现ChannelOutboundHandler接口,ChannelOutboundHandler就是专门用于处理出站事件的。

在这里插入图片描述

ChannelInboundHandler和ChannelOutboundHandler都继承了ChannelHandler接口。

在这里插入图片描述

但是ChannelInboundHandler和ChannelOutboundHandler有许多不同类型事件对应的方法,如果直接实现ChannelInboundHandler或ChannelOutboundHandler,我们要一一编写每个方法的实现逻辑。但是我们可能不会全部事件都关注,可能只会关注一两种类型的事件。

于是我们可以通过继承Netty提供的适配器类来实现我们的ChannelHandler,我们就可以选择性的实现我们关注的事件类型对应的方法。Netty提供的适配器类就是ChannelInboundHandlerAdapter和ChannelOutboundHandlerAdapter,ChannelInboundHandlerAdapter是用于处理入站事件的适配器类,ChannelOutboundHandlerAdapter是用于处理出站事件的适配器类。

在这里插入图片描述

ChannelInboundHandlerAdapter实现了ChannelInboundHandler接口,而ChannelOutboundHandlerAdapter则实现了ChannelOutboundHandler接口。

在这里插入图片描述

ChannelPipeline

在Netty中,每个Channel对应一个ChannelPipeline。在Channel初始化的时候,就会为Channel创建一个对应的ChannelPipeline。ChannelPipeline是一个由多个ChannelHandler组成的双向链表,ChannelPipeline中有固定的head(头部Handler)和tail(尾部Handler)。

在这里插入图片描述

ChannelPipeline中除head和tail以外的ChannelHandler可以通过ChannelInitializer进行安装,一开始ChannelPipeline中除head和tail以外,中间只有一个ChannelInitializer。当Channel(NIO的Channel)被注册到Selector中时,会触发ChannelInitializer的调用,安装指定的ChannelHandler到Pipeline中,并把自己从链表中删除。

在这里插入图片描述

ChannelPipeline中对应就绪事件的处理,就是调用ChannelPipeline中的ChannelHandler与就绪事件匹配的方法。如果是入栈事件,则会以从head到tail的方向逐一调用负责处理入站事件的ChannelHandler来处理;如果是出站事件,则会以tail到head的方向逐一调用负责处理出站事件的ChannelHandler来处理。

在这里插入图片描述

ChannelHandlerContext

其实ChannelPipeline中的双向链表并不是由ChannelHandler直接组成的双向链表,而是在ChannelHandler外头再包了一层ChannelHandlerContext,因为ChannelHandler本身并没有维护组成双向链表需要的前后指针,ChannelHandlerContext才维护了这个前后指针,也就是说ChannelPipeline里头是由ChannelHandlerContext组成的双向链表。

在这里插入图片描述

之所以要在ChannelHandler之上再包一层ChannelHandlerContext来组成链表,是出于单一职责的考虑。首先ChannelHandler是用来处理事件的,那么ChannelHandler就应该只关注事件的处理,让它去维护前后指针就不太合适。就像LinkedList一样,我们放进去的元素,也不是直接组成双向链表的,LinkedList里头也是会包一个Node,再由Node的前后指针组成双向链表。

以下是ChannelHandlerContext的一些常用方法:
在这里插入图片描述

其中fireXxx是ChannelHandlerContext定义的以fire开头的一些方法,这些方法都是用于触发ChannelHandler中不同类型的事件处理方法,一旦调用这些方法,就会从当前ChannelHandlerContext开始沿着责任链调用每个ChannelHandler对应的事件的处理方法。比如调用了当前ChannelHandlerContext的fireChannelRead(Object msg)方法,就会从当前ChandlerHandlerContext对应的ChandlerHandler开始,沿着责任链顺序调用每个ChandlerHandler的channelRead(…)方法。

在这里插入图片描述

ChannelFuture

Netty中的操作都是异步操作,比如我们通过Bootstrap的connect(String inetHost, int inetPort)连接服务器、通过ServerBootstrap的bind(int inetPort)监听某个端口等,这些都是异步操作。这些异步操作都会返回一个ChannelFuture,我们可以通过ChannelFuture的addListener(…)方法添加一个ChannelFutureListener,等Netty的异步操作完成后,会触发添加到ChannelFuture的ChannelFutureListener进行相应的处理。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1808565.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

代码随想录算法训练营第36期DAY56

DAY56 套磁很顺利&#xff0c;发现又有书读了&#xff01; 300最长递增子序列 朴素法&#xff0c;这个好想&#xff0c;但是不对&#xff0c;比如 0 1 0 3 2 3 我的算法会找出0 1 3作为答案&#xff0c;而不是0 1 2 3 可以看出&#xff0c;后面的状态依赖于前面的状态&am…

ELK组件

资源列表 操作系统 IP 主机名 Centos7 192.168.10.51 node1 Centos7 192.168.10.52 node2 部署ELK日志分析系统 时间同步 chronyc sources -v 添加hosts解析 cat >> /etc/hosts << EOF 192.168.10.51 node1 192.168.10.52 node2 EOF 部署Elasticsea…

Oracle10.2.0.1冷备迁移之_数据文件拷贝方式

由于阿里云机房要下架旧服务器&#xff0c;单位未购买整机迁移服务&#xff0c;且业务较老不兼容Oracle11g&#xff0c;所以新购买一台新服务器进行安装Oracle10.2.0.1 &#xff0c;后续再将数据迁移到新服务器上。 id 数据库版本 操作系统版本 实例名 源库 115.28.242.25…

[数据集][目标检测]厨房积水检测数据集VOC+YOLO格式88张2类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;88 标注数量(xml文件个数)&#xff1a;88 标注数量(txt文件个数)&#xff1a;88 标注类别数…

tcp协议的延迟应答(介绍+原则),拥塞控制(拥塞窗口,网络出现拥塞时,滑动窗口的大小如何确定,慢启动,阈值)

目录 延迟应答 引入 介绍 原则 拥塞控制 引入 网络出现拥塞 引入 介绍 介绍 拥塞窗口 介绍 决定滑动窗口的大小 慢启动 介绍 为什么要有慢启动 阈值 算法 总结 延迟应答 引入 发送方一次发送更多的数据,发送效率就越高 因为要写入网卡硬件的io速度很慢,尽量…

Chroium 源码目录结构分析(1):源码目录体积一栏

获取源码 首先&#xff0c;我们拉一份最新的源代码&#xff08;笔者是2024.6.6日拉取的&#xff09;&#xff1a; fetch --nohistory chromium 源码预处理 如果运行build&#xff0c;会生成许多生成的代码&#xff0c;因此我们不运行build。 然后&#xff0c;把干扰后续分析…

Python Requests库详解

大家好&#xff0c;在现代网络开发中&#xff0c;与Web服务器进行通信是一项至关重要的任务。Python作为一种多才多艺的编程语言&#xff0c;提供了各种工具和库来简化这一过程。其中&#xff0c;Requests库作为Python中最受欢迎的HTTP库之一&#xff0c;为开发人员提供了简单而…

python实践笔记(一): 模块和包

1. 写在前面 最近在重构之前的后端代码&#xff0c;借着这个机会又重新补充了关于python的一些知识&#xff0c; 学习到了一些高效编写代码的方法和心得&#xff0c;比如构建大项目来讲&#xff0c;要明确捕捉异常机制的重要性&#xff0c; 学会使用try...except..finally&…

AI服务器相关知识

在当今社会&#xff0c;人工智能的应用场景愈发广泛&#xff0c;如小爱同学、天猫精灵等 AI 服务已深入人们的生活。随着人工智能时代的来临&#xff0c;AI 服务器也开始在社会各行业发挥重要作用。那么&#xff0c;AI 服务器与传统服务器相比&#xff0c;究竟有何独特之处&…

C-MAPSS数据集探索性分析

实验数据为商用模块化航空推进系统仿真C-MAPSS数据集&#xff0c;该数据集为NASA格林中心为2008年第一届预测与健康管理国际会议(PHM08)竞赛提供的引擎性能退化模拟数据集&#xff0c;数据集整体信息如下所示&#xff1a; 涡扇发动机仿真模拟模型如下图所示。 仿真建模主要针对…

【AI大模型】Transformers大模型库(五):AutoModel、Model Head及查看模型结构

目录​​​​​​​ 一、引言 二、自动模型类&#xff08;AutoModel&#xff09; 2.1 概述 2.2 Model Head&#xff08;模型头&#xff09; 2.3 代码示例 三、总结 一、引言 这里的Transformers指的是huggingface开发的大模型库&#xff0c;为huggingface上数以万计的预…

写给大数据开发,如何去掌握数据分析

这篇文章源于自己一个大数据开发&#xff0c;天天要做分析的事情&#xff0c;发现数据分析实在高大上很多&#xff0c;写代码和做汇报可真比不了。。。。 文章目录 1. 引言2. 数据分析的重要性2.1 技能对比2.2 业务理解的差距 3. 提升数据分析能力的方向4. 数据分析的系统过程4…

计算机提示msvcp120.dll如何修复,7个不同方法分享

msvcp120.dll 是 Microsoft Visual C Redistributable 的一个关键组件&#xff0c;它包含了 C 运行时库&#xff0c;这些库对基于 Visual C 编写的应用程序至关重要。当应用程序运行时&#xff0c;msvcp120.dll 会被加载到内存中以提供必要的函数和类支持。 一、msvcp120.dll功…

springboot与flowable(2):流程部署

一、创建项目 创建springboot项目添加相关依赖。 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.…

Android安全开发之 Provider 组件安全

Android系统中的Content Provider组件是一种用于在不同应用之间共享数据的机制。它提供了一种安全、可控的方式&#xff0c;允许应用访问其他应用的数据。然而&#xff0c;如果Provider组件的安全措施没有得到妥善实现&#xff0c;则可能会导致严重的安全漏洞&#xff0c;例如数…

深入理解C语言:main函数的奥秘

在C语言中&#xff0c;main函数是每个程序的入口点&#xff0c;起着至关重要的作用。本文将深入探讨main函数的工作原理&#xff0c;包括其参数、返回值、以及如何从main启动程序的执行。通过实际代码示例&#xff0c;读者将更深入地理解main函数在C语言编程中的核心地位。 第一…

SQL自动发送邮件的方法有哪些?如何配置?

SQL自动发送邮件设置时的注意事项&#xff1f;邮件群发如何操作&#xff1f; 在现代企业中&#xff0c;自动化流程越来越普遍&#xff0c;SQL自动发送邮件作为其中一项重要功能&#xff0c;能够大大提高工作效率并简化数据管理流程。AokSend将介绍几种实现SQL自动发送邮件的方…

MySQL限制登陆失败次数配置

目录 一、限制登陆策略 1、Windows 2、Linux 一、限制登陆策略 1、Windows 1&#xff09;安装插件 登录MySQL数据库 mysql -u root -p 执行命令安装插件 #限制登陆失败次数插件 install plugin CONNECTION_CONTROL soname connection_control.dll;install plugin CO…

探索软件工程师在新能源汽车研发中的角色与贡献

随着全球对可持续发展的关注不断增加&#xff0c;新能源汽车的研发与应用成为了汽车行业的一个重要方向。作为软件工程师&#xff0c;参与新能源汽车研发不仅能够推动科技创新&#xff0c;还能为环保事业贡献力量。本文将深入探讨软件工程师在新能源汽车研发中的具体贡献、所需…

VISIO安装教程+安装包

文章目录 01、什么是VISIO&#xff1f;02、安装教程03、常见安装问题解析 01、什么是VISIO&#xff1f; Visio是由微软开发的流程图和图表绘制软件&#xff0c;它是Microsoft Office套件的一部分。Visio提供了各种模板和工具&#xff0c;使用户能够轻松创建和编辑各种类型的图…