Netty核心组件
1.Channel
Channel可以理解为是socket连接,在客户端与服务端连接的时候就会建立一个Channel,它负责基本的IO操作(binf()、connect()、rad()、write()等);
1.1 Channel的作用
- 通过Channel可获得当前网络连接的通道状态;
- 通过Channel可获得网络连接的配置参数(缓冲区大小等);
- Channel提供异步的网络IO操作,如连接的建立、数据的读写、端口的绑定等;
1.2 Channel的类型
- NioSocketChannel:NIO的客户端TCP socket连接;
- NioServerSocketChannel:NIO的服务器端TCP socket连接;
- NioDatagramChannel:UDP连接;
- NioSctpChannel:客户端Sctp(一种传输层协议)连接;
- NioSctpServerChannel:Sctp服务器端连接;
2.Event Loop、Event Loop Group
有了Channel连接服务,消息就可以流动,针对消息在服务器上的出站入站产生事件,而EventLoop就是一个监控和协调事件的机制;
Netty中每个Channel都会分配一个EventLoop,一个EventLoop可以服务于多个Channel,每个EventLoop会占用一个线程,同时这个线程会处理Event Loop上面发生的所有IO操作和事件;
而EventLoopGroup是用来生成EventLoop的,默认线程数为CPU核数*2;
3.ChannelHandler
数据的入站和出站的业务逻辑都是在ChannelHandler中,针对出入站分为ChannelInboundHandler(入站事件处理器)和ChannelOutBoundHandler(出站事件处理器),两个接口都继承ChannelHandler接口;
ChannelHandlerAdapter抽象类实现了ChannelHandler接口,提供了一些方法的默认实现,根据在服务端编写还是在客户端编写提供了ChannelInboundHandlerAdapter与SimpleChannelInboundHandler两个子类,前者不会释放消息数据的引用,后者会;

4.ChannelPipeline
在Channel的数据传递过程中,不同的业务逻辑实现都需要有ChannelHandler完成,一个Channel对应着多个ChannelHandler,ChannelPipeline就是用来管理多个ChannelHandler的;
一个Channel包含了一个ChannelPipeline,ChannelPipeline中维护了一个ChannelHandler的列表,ChannelHandler与Channel和ChannelPipeline之间的映射关系又由ChannelHandlerContext来维护;

- Channel Handler按照加入的顺序会组成一个双向链表,入站事件从链表的头往后传递到最后一个ChannelHandler,出站事件从链表的尾向前传递,直到最后一个ChannelHandler,两种类型的ChannelHandler相互不影响;
5.Bootstrap
Bootstrap(引导类)负责配置整个Netty程序,将各个组件都串起来,绑定端口启动Netty服务,针对客户端(Bootstrap)与服务端(ServerBootstrap)分为两种引导类;
- ServerBootstrap将绑定到一个端口,而Bootstrap不需要绑定本地端口只需连接到远程端口;
- Bootstrap只需要一个EventLoopGroup,而Server Bootstrap则需要两个,因为服务端需要两组不同的Channel,一组用来接收新的客户端连接请求,一组用来处理已连接的客户端Channel的读写事件;
6.Future
Future提供了一种在异步操作完成时通知应用程序的方式,Future对象可以看作一个异步操作结果的占位符,他将在未来的某个时刻完成,并提供对其结果的访问;
JDK内置的 java.util.concurrent.Future只允许手动检查对应的操作是否已完成,或阻塞到他完成,较为繁琐,Netty提供了他自己的Future实现--ChannelFuture;
- ChannelFuture提供了几种额外的方法,使得我们能够注册一个或多个ChannelFutureListener实例;
- 监听器的回调方法operationComplete(),将会在对应的操作完成时被调用,监听器就能知道操作是成功了还是出错了;
- 每个Netty的出站IO操作都将返回一个ChannelFuture,也就是说他们都不会阻塞;
7.ByteBuf缓冲区
ByteBuf是Netty用于处理字节数据的核心类,是一个灵活高效的字节容器,提供了丰富的API来操作字节数据,是Netty对JDK自带的ByteBuffer的替代品;
ByteBuf内部结构如下:

- discardable bytes:可丢弃的字节空间;
- readable bytes:可读的字节空间;
- writable bytes:可写的字节空间;
- capacity bytes:最大的可容量空间;
7.1 ByteBuf的工作原理
ByteBuf由一串字节数组构成,数组中每个字节用来存放信息,ByteBuf有两个索引,分别用来读写数据,通过两个索引在数组中移动,来定位需要读或写的位置;
当从ByteBuf中读取时,readerIndex(读索引)将会根据读取的字节数递增,当写ByteBuf时,writerIndex(写索引)也会根据写入的字节数进行递增;当readerIndex超过writerIndex的时候,Netty会抛出IndexOutOf-BoundsException;
7.2 索引指针

ByteBuf有三个指针:
- readerIndex(读指针):标记读取的起始位置,每读取一个字节加一,当readerIndex与writerIndex相等时不可读;
- writerIndex(写指针):标记写入的起始位置,每写入一个字节加一,当writerIndex与maxCapacity容量相等时不可写;
- maxCapacity(最大容量):指示ByteBuf可以扩容的最大容量,如果向ByteBuf写入数据时容量不足,可以扩容;
7.3 缓冲区的使用模式
根据存放缓冲区的不同分为三类:
- 堆缓冲区(HeapByteBuf):内存的分配和回收速度比较快,可以被JVM自动回收,但如果进行socket的IO读写,需要额外做一次内存复制,将堆内存对应的缓冲区复制到内核Channel中,这回对性能有所影响;
- 直接缓冲区(DirectByteBuf):非堆内存,相较比堆内存分配和回收速度慢一些,但是将他写入或从socket Channel中读取时少一次内存拷贝,这时比堆内存快;
- 复合缓冲区:Netty提供的CompsiteByteBuf就是将堆缓冲区与直接缓冲区的数据放在一起;
Nettty默认使用直接缓冲区模式;
7.4 ByteBuf的分配
Netty提供了接口ByteBufAllocator来分配ByteBuf实例,其有两个实现类
- PooledByteBufAllocator:实现了ByteBuf对象的池化,可复用ByteBuf实例,提高性能并最大限度的减少内存碎片;
- UnpooledByteBufAllocator:没有实现对象的池化,每次会生成新的ByteBuf对象实例;
7.5 ByteBuf的释放
ByteBuf如果采用堆缓冲区模式,可以由GC回收,如果采用直接缓冲区模式就得手动释放;
7.5.1 手动释放
使用完后,调用 ReferenceCountUtil.release(byteBuf) 来释放;
7.5.2 自动释放
- TailHandler:Netty的ChannelPiplelline的流水线的末端是TailHandler,默认情况下如果每个入站处理器都把消息往下传,TailHandler会释放掉ReferenceCounted类型的消息;
- SImpleChannelInboundHandler:当ChannelHandler继承了SimpleChannelInboundHandler后,在其中的channelRead()方法中,将会进行资源的释放,业务代码需要写入到channelRead0()中;

- HeadHandler:在每一个出站Handler中的处理完成后,最后消息会来到HeadHandler,经过一轮复杂调用在flush完成后释放掉;
7.5.3 释放总结
- 入站处理流程中,如果对原消息不做处理,调用 ctx.fireChannelRead(msg) 把原消息往下传,由流水线最后的 TailHandler 完成自动释放。
- 如果截断了入站处理流水线,则可以继承 SimpleChannelInboundHandler ,完成入站ByteBuf自动释放。
- 出站处理过程中,申请分配到的 ByteBuf,通过 HeadHandler 完成自动释放。
- 入站处理中,如果将原消息转化为新的消息并调用 ctx.fireChannelRead(newMsg)往下传,那必须把原消息release掉;
- 入站处理中,如果已经不再调用 ctx.fireChannelRead(msg) 传递任何消息,也没有继承SimpleChannelInboundHandler 完成自动释放,那更要把原消息release掉;
相关文章:
Netty核心组件
1.Channel Channel可以理解为是socket连接,在客户端与服务端连接的时候就会建立一个Channel,它负责基本的IO操作(binf()、connect()、rad()、write()等); 1.1 Channel的作用 通过Channel可获得当前网络连接的通道状态…...
Windows中如何安装SSH
主要内容 一、参考资料二、主要过程法一:通过「设置」安装法二:使用 PowerShell进行安装在 Windows 中配置 OpenSSH 服务器过程截图 一、参考资料 Windows10 打开ssh服务,报错“The service name is invalid ” windows开启ssh服务教程 在 W…...
在linux上部署ollama+open-webu,且局域网访问教程
在linux上部署ollamaopen-webu,且局域网访问教程 运行ollamaopen-webui安装open-webui (待实现)下一期将加入内网穿透,实现外网访问功能 本文主要介绍如何在Windows系统快速部署Ollama开源大语言模型运行工具,并使用Op…...
基于大模型的招聘智能体:从创意到MVP
正在考虑下一个 SaaS 创意?以下是我在短短几个小时内从创意到 MVP 的过程。 以下是我将在这篇文章中介绍的内容概述: 为什么这个想法让我产生共鸣我是如何开始构建它的我现在的处境以及我是否会真正推出 获得 SaaS 创意并构建它并不容易。就是这样。 …...
STM32F1+HAL库+FreeTOTS学习19——软件定时器
STM32F1HAL库FreeTOTS学习19——软件定时器 1 软件定时器1.1 FreeRTOS软件定时器简介1.2 FreeRTOS软件定时器服务任务1.3 FreeRTOS软件定时器服命令队列。1.4 软件定时器的状态1.5 复位定时器1.6 软件定时器结构体 2 软件定时器配置3 软件定时器API函数3.1 xTimerCreate()和xTi…...
@RequestBody的详解和使用
RequestBody的详解和使用 提示:建议一定要看后面的RequestBody的核心逻辑源码以及六个重要结论!本文前半部分的内容都是一些基- 本知识常识,可选择性跳过。 声明:本文是基于SpringBoot,进行的演示说明。 基础知识介…...
VMware介绍及常见使用方法
VMware 是一家全球知名的虚拟化和云计算软件提供商。以下是关于 VMware 的详细介绍: 一、主要产品和功能 VMware vSphere 服务器虚拟化平台,允许将物理服务器虚拟化为多个虚拟机(VM)。提供高可用性、资源管理、动态迁移等功能,确保业务的连续性和高效性。通过集中管理控制…...
Deepinteraction 深度交互:通过模态交互的3D对象检测
一.前提 为什么要采用跨模态的信息融合? 点云在低分辨率下提供必要的定位和几何信息,而图像在高分辨率下提供丰富的外观信息。 -->因此必须采用跨模态的信息融合 提出的原因? 传统的融合办法可能会由于信息融合到统一表示中的不太完美而丢失很大一部分特定…...
开展物业满意度调查的策略与注意事项
(专业物业满意度调查公司)在物业管理领域,满意度调查是一项重要的工作,可以帮助物业公司了解居民的需求和期望,及时发现并解决问题,提升服务质量。民安智库作为专业调查咨询机构,拥有丰富的实战…...
如何使用 Maven 不同环境使用不同资源文件 提升项目安全性
需求: 之前的文章介绍过,不同环境,配置文件可以灵活构建,参考Maven 不同环境灵活构建。 进一步的,打包时时可以进一步优化,即开发环境,构建时只将测试资源文件打包到应用中,进一步提…...
QT 如何置顶窗口并激活
基本上,客户端软件都会有置顶某个窗口的需求。置顶窗口激活窗口,两者不是同一个问题。有时候窗口置顶了,并不代表该窗口属于激活状态。本文将尝试把这两个问题一起解决了,请看下文: 一、置顶窗口 通过函数setWindowF…...
嵌入式面试刷题(day19)
Makefile和Cmake的区别 Makefile 和 CMake 都是用于构建和管理软件项目的工具,但它们有不同的设计理念和使用方式。以下是二者的主要区别: 1. 概念和工作原理 Makefile: Makefile 是 make 工具的配置文件,定义了如何编译和链接程序。它基于文件的时间戳,使用规则(规则指…...
Robot Framework命令和Tag运用
前面的文章中我们为大家介绍了市面上常见自动化测试框架的解读以及Robot Framework的环境搭建,本文我们继续为大家介绍Robot Framework命令和Tag的运用,首先我们先一起看一下Robot Framework有哪些命令。 Robot Framework命令 先来看这一条:…...
软件分享丨PDF Shaper
【资源名】PDF Shaper 【地址】https://www.pdfshaper.com/ 【资源介绍】 PDF Shaper Professional是一款功能强大的PDF文档编辑与转换工具,使用它可以对PDF文件进行各种转换、提取、合并、旋转、加密、解密等编辑操作,主要功能有分割和合并PDF文件&…...
pytorch的标签平滑介绍
什么是标签平滑(Label Smoothing)? 标签平滑(Label Smoothing)是一种正则化技术,旨在防止模型过度自信(即输出的概率分布过于“尖锐”)。在分类任务中,标准的目标标签是one-hot编码,也就是正确类别的概率为 1,其他类别的概率为 0。而标签平滑通过将正确类别的概率从…...
CTE 与存储过程:SQL 查询简化与复杂业务逻辑处理的最佳选择
CTE(Common Table Expression,公共表表达式)和存储过程是两种不同的SQL工具,分别用于解决不同的问题。它们各有优缺点,适用于不同的场景。让我们从以下几个方面来比较它们: 1. 定义与作用 CTE:…...
mysql delete命令操作后,数据库文件大小并未变化,该怎么解决?
在 MySQL 中,使用 DELETE 命令删除数据后,数据表的大小可能不会立即减小,因为 MySQL 并不总是立即回收已删除数据所占用的空间。这是因为 MySQL 的存储引擎(如 InnoDB)可能会保留这些空间以备将来插入新数据时使用&…...
GitLab 发布安全补丁版本 17.3.2, 17.2.5, 17.1.7
本分分享极狐GitLab 补丁版本 17.4.2, 17.3.5, 17.2.9 的详细内容。这几个版本包含重要的缺陷和安全修复代码,我们强烈建议所有私有化部署用户应该立即升级到上述的某一个版本。对于极狐GitLab SaaS,技术团队已经进行了升级,无需用户采取任何…...
data_table_2 与 flutter 官方 DataTable 的区别
data_table_2 与 flutter 官方 DataTable 的区别 https://blog.csdn.net/ken2232/article/details/143181634 flutter 数据表增强库 data_table_2 错误问题 记录 (****) https://blog.csdn.net/ken2232/article/details/143180018 data_table_2 与 flutter 官方 DataT…...
TRIZ创新方法培训值得去吗?
面对日益复杂的市场环境和竞争态势,掌握有效的创新方法不仅关乎企业的生死存亡,也直接关系到个人的职业成长与竞争力。TRIZ作为一种系统化的创新方法论,其培训课程正逐渐受到企业和个人的广泛关注。那么,TRIZ创新方法培训究竟值得…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...
保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek
文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama(有网络的电脑)2.2.3 安装Ollama(无网络的电脑)2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...
【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...
LLMs 系列实操科普(1)
写在前面: 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容,原视频时长 ~130 分钟,以实操演示主流的一些 LLMs 的使用,由于涉及到实操,实际上并不适合以文字整理,但还是决定尽量整理一份笔…...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...
