netty基础知识梳理和总结

目录标题

    • 由来
    • netty整体结构
        • 核心功能
          • 可扩展的事件模型
          • 统一的通信 API
          • 零拷贝机制与字节缓冲区
        • 传输服务
        • 协议支持
    • netty的IO模型
    • netty核心组件
        • Channel
        • EventLoop、EventLoopGroup
        • ChannelHandler
        • ChannelPipeline
        • Bootstrap
        • Future
    • netty的bytebuf
      • bytebuf的内部构造
      • bytebuf的使用模式
      • ByteBuf的释放
    • netty的零拷贝
      • Kafka的零拷贝
      • **1. Kafka 的零拷贝**
        • **定义**
        • **实现原理**
        • **优点**
        • **缺点**

由来

Netty是由JBOSS公司提供的一个java开源框架
是一个基于NIO的客户、服务器端编程框架,用以快速开发高性能、高可靠性的网络服务器和客户端程序。

netty整体结构

在这里插入图片描述

核心功能
可扩展的事件模型
  • 提供灵活且可扩展的事件处理机制,适应多种应用场景。
统一的通信 API
  • 统一接口:无论是 HTTP 还是 Socket,均使用统一的 API,简化了操作流程。
  • 易用性:通过一致的接口设计,降低了开发复杂度。
零拷贝机制与字节缓冲区
  • 高效数据传输:采用零拷贝机制,减少数据在内存中的拷贝次数,提升性能。
  • 字节缓冲区:优化数据存储和读取效率。
传输服务
  • Socket,基于TCP
  • Datagram(数据报),基于UDP
  • HTTP 协议
  • In-VM Pipe(管道协议)
协议支持
  • HTTP 与 WebSocket:支持标准的 HTTP 和 WebSocket 协议。
  • SSL 安全套接字协议:提供安全的通信保障。
  • Google Protobuf:支持高效的序列化框架。
  • 压缩支持
    • 支持 zlibgzip 压缩,优化传输效率。
  • 大文件传输:支持高效的大文件传输能力。
  • RTSP(实时流传输协议):支持 TCP/IP 协议体系中的应用层协议,适用于实时流媒体场景。
  • 二进制协议支持:支持自定义二进制协议,并提供完整的单元测试。

netty的IO模型

Netty就是使用Java的NIO实现了Reactor线程模型是其实现高性能的一个核心点。
Netty是基于NIO2的IO模型(IO多路复用模型,非循环进行read的系统调用的原始NOBlock IO模型)。

  • 常见的Reactor线程模型有三种
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

Netty就是结合了NIO的特点,应用了Reactor线程模型所实现的。

在这里插入图片描述

  • 在Netty模型中,负责处理新连接事件的是BossGroup,负责处理其他事件的是WorkGroup。Group就是线程池的概念。
  • NioEventLoop表示一个不断循环的执行处理任务的线程,用于监听绑定在其上的读/写事件。NioEventLoop就是Group里面的工作线程。
  • 通过Pipeline(管道)执行业务逻辑的处理,Pipeline中会有多个ChannelHandler,真正的业务逻辑是在ChannelHandler中完成的。

netty核心组件

Channel

可以理解为是socket连接,在客户端与服务端连接的时候就会建立一个Channel。
常用的 Channel 类型:

  • NioSocketChannel,NIO的客户端 TCP Socket 连接。
  • NioServerSocketChannel,NIO的服务器端 TCP Socket 连接。
  • NioDatagramChannel, UDP 连接。
  • NioSctpChannel,客户端 Sctp 连接。
  • NioSctpServerChannel,Sctp 服务器端连接,这些通道涵盖了 UDP 和 TCP 网络 IO 以及文件IO。
EventLoop、EventLoopGroup
  • 在 Netty 中每个 Channel 都会被分配到一个 EventLoop。一个 EventLoop 可以服务于多个 Channel。
  • 每个 EventLoop 会占用一个 Thread,同时这个 Thread 会处理 EventLoop 上面发生的所有 IO 操作和事件
  • EventLoopGroup 是用来生成 EventLoop 的
ChannelHandler

ChannelHandler对使用者而言,可以说是最重要的组件了,因为对于数据的入站和出站的业务逻辑的编写都是在ChannelHandler中完成的。
在这里插入图片描述

  • ChannelInboundHandler 入站事件处理器
  • ChannelOutBoundHandler 出站事件处理器

例如:在 入站事件处理器中可以实现了channelRead方法,获取到客户端传来的数据
ChannelHandler只能完成编码解码处理、读写操作中的一种,所以ChannelHandler都是成组出现来完成功能。

ChannelPipeline

一个Channel包含了一个ChannelPipeline,而ChannelPipeline中维护了一个ChannelHandler的列表。
ChannelHandlerContext进行维护ChannelHandler与Channel和ChannelPipeline之间的映射关系。
在这里插入图片描述
ChannelHandler按照加入的顺序会组成一个双向链表

  • 入站事件从链表的head往后传递到最后一个ChannelHandler
  • 出站事件从链表的tail向前传递,直到最后一个ChannelHandler
  • 两种类型的ChannelHandler相互不会影响。
Bootstrap

Bootstrap是引导的意思,它的作用是配置整个Netty程序,将各个组件都串起来,最后绑定端口、启动Netty服务。
Netty中提供了2种类型的引导类,一种用于客户端(Bootstrap),而另一种(ServerBootstrap)用于服务器。
它们的区别在于:

  • ServerBootstrap 只需要绑定一个监听连接的端口,而 Bootstrap 则是需要远程节点的IP和端口
  • 客户端Bootstrap 只需要一个EventLoopGroup来实现消息的读取和写入,而ServerBootstrap则需要两个EventLoopGroup,一个来实现处理新连接事件,一个用来处理消息的读取和写入等事件。
Future

Future提供了一种在操作完成时通知应用程序的方式。这个对象可以看作是一个异步操作的结果的占位符,它将在未来的某个时刻完成,并提供对其结果的访问。

netty的bytebuf

bytebuf的内部构造

ByteBuf的三个指针:

  • readerIndex(读指针)
    指示读取的起始位置, 每读取一个字节, readerIndex自增累加1。 如果readerIndex 与writerIndex 相等,ByteBuf 不可读 。
  • writerIndex(写指针)
    指示写入的起始位置, 每写入一个字节, writeIndex自增累加1。如果增加到 writerIndex 与capacity() 容量相等,表示 ByteBuf 已经不可写。
  • maxCapacity(最大容量)
    指示ByteBuf 可以扩容的最大容量, 如果向ByteBuf写入数据时, 容量不足, 可以进行扩容

当从 ByteBuf 读取时,它的 readerIndex(读索引)将会根据读取的字节数递增。
同样,当写 ByteBuf 时,它的 writerIndex(写索引) 也会根据写入的字节数进行递增。

ByteBuf内部空间结构:
在这里插入图片描述

  • byteBuf.readByte(),内部通过移动readerIndex进行读取
  • byteBuf.writeInt(i);
  • discardReadBytes(),可以将已经读取的数据进行丢弃处理,就可以回收已经读取的字节空间,可写空间就会变大
  • clear() ,重置readerIndex 、 writerIndex 为0,需要注意的是,重置并没有删除真正的内容

bytebuf的使用模式

  • 堆缓冲区(HeapByteBuf)
    • 优点:内存的分配和回收速度比较快,可以被JVM自动回收
    • 缺点:进行socket的IO读或者写时,需要额外做一次内存复制,,将堆内存对应的缓冲区复制到内核Channel中,性能下降。
  • 直接缓冲区(DirectByteBuf),非堆内存
    • 优点:它写入或从Socket Channel中读取时,由于减少了一次内存拷贝(零拷贝),速度比堆内存块
    • 缺点:内存的分配和回收速度慢,并且如果不注意内存回收,会导致内存泄漏
  • 复合缓冲区,顾名思义就是将上述两类缓冲区聚合在一起。
    • 复合缓冲区的核心思想是通过逻辑上的组合,而不是物理上的合并,来管理多个缓冲区
    • 工作原理
      • 数据的逻辑组合:通过维护一个内部的组件列表(components),记录每个子缓冲区的引用和偏移量。每个子缓冲区可以是堆缓冲区或直接缓冲区。
      • 统一的读写接口:复合缓冲区对外提供了一个统一的读写接口,用户可以通过索引访问整个缓冲区的内容,而不需要关心底层是由哪些子缓冲区组成的。
    • 使用场景:在网络协议中,可能需要将头部(通常较小,适合堆缓冲区)和负载(通常较大,适合直接缓冲区)分开存储,但又希望以统一的方式操作。

ByteBuf的释放

  • 手动释放,就是在使用完成后,调用ReferenceCountUtil.release(byteBuf); 进行释放
  • 自动释放
    • 入站的TailHandler:Netty的ChannelPipleline的流水线的末端是TailHandler,默认情况下如果每个入站处理器Handler都把消息往下传,TailHandler会释放掉ReferenceCounted类型的消息。
    • 继承SimpleChannelInboundHandler,类中包含一个onUnhandledInboundMessage方法,会释放缓存
    • HeadHandler的出站释放,类似于入站

netty的零拷贝

所谓的零拷贝,就是取消用户空间与内核空间之间的数据拷贝操作,应用进程每一次的读写操作,都可以通过一种方式,让应用进程向用户空间写入或者读取数据,就如同直接向内核空间写入或者读取数据一样,再通过 DMA 将内核中的数据拷贝到网卡,或将网卡中的数据 copy 到内核。

Netty零拷贝主要体现在三个方面:

  • Netty的接收和发送ByteBuffer是采用DIRECT BUFFERS,使用堆外的直接内存(内存对象分配在JVM中堆以外的内存)进行Socket读写,不需要进行字节缓冲区的二次拷贝。如果采用传统堆内存(HEAP BUFFERS)进行Socket读写,JVM会将堆内存Buffer拷贝一份到直接内存中,然后写入Socket中。
  • Netty提供了组合Buffer对象,也就是CompositeByteBuf 类,可以将 ByteBuf 分解为多个共享同一个存储区域的 ByteBuf,避免了内存的拷贝。
  • Netty的文件传输采用了FileRegion 中包装 NIO 的 FileChannel.transferTo() 方法,它可以直接将文件缓冲区的数据发送到目标Channel,避免了传统通过循环write方式导致的内存拷贝问题。(类似于kafka的零拷贝)

Kafka的零拷贝

Kafka 和 Netty 都使用了零拷贝技术,但它们的应用场景和实现方式有所不同。以下是对两者的区别、优缺点的详细分析:


1. Kafka 的零拷贝

定义

Kafka 的零拷贝是指在数据传输过程中,尽量减少数据在用户空间和内核空间之间的拷贝次数。它主要依赖于操作系统提供的 sendfile 系统调用(Linux 环境下)来实现。

实现原理
  • 当 Kafka 从磁盘读取数据并发送到网络时,传统的方式需要经过多次数据拷贝:
    1. 数据从磁盘读取到内核缓冲区。
    2. 数据从内核缓冲区拷贝到用户空间缓冲区。
    3. 数据从用户空间缓冲区再拷贝回内核缓冲区(用于网络传输)。
    4. 数据通过网络接口发送出去。
  • 使用零拷贝后:
    • 数据直接从内核缓冲区通过 sendfile 系统调用传输到网络接口,避免了用户空间的参与,减少了两次拷贝操作。
优点
  1. 性能提升:减少了数据拷贝次数和上下文切换,显著提高了吞吐量。
  2. 降低 CPU 开销:避免了用户空间和内核空间之间的数据拷贝,降低了 CPU 的负担。
  3. 适合大数据传输:特别适用于 Kafka 这种需要频繁进行大文件传输的场景。
缺点
  1. 灵活性较低:零拷贝要求数据是连续存储的,且不能对数据进行修改。如果需要对数据进行处理(如加密、压缩等),则无法直接使用零拷贝。
  2. 依赖操作系统支持:需要底层操作系统提供 sendfile 或类似机制的支持。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《Head First设计模式》读书笔记 —— 单件模式

文章目录 为什么需要单件模式单件模式典型实现剖析定义单件模式本节用例多线程带来的问题解决问题优化 Q&A总结 《Head First设计模式》读书笔记 相关代码: Vks-Feng/HeadFirstDesignPatternNotes: Head First设计模式读书笔记及相关代码 用来创建独一无二的&a…

tailwindcss 前端 css 框架 无需写css 快速构建页面

版本:VUE3 TS 框架 vite 文章中使用tailwindcss 版本: ^3.4.17 简介: Tailwind CSS 一个CSS 框架,提供组件化的样式,直接在HTML 中编写样式,无需额外自定义CSS ,快速! 简洁&#…

给小米/红米手机root(工具基本为官方工具)——KernelSU篇

目录 前言准备工作下载刷机包xiaomirom下载刷机包【适用于MIUI和hyperOS】“hyper更新”微信小程序【只适用于hyperOS】 下载KernelSU刷机所需程序和驱动文件 开始刷机设置手机第一种刷机方式【KMI】推荐提取boot或init_boot分区 第二种刷机方式【GKI】不推荐 结语 前言 刷机需…

路由器的WAN口和LAN口有什么区别?

今时今日,移动终端盛行的时代,WIFI可以说是家家户户都有使用到的网络接入方式。那么路由器当然也就是家家户户都不可或缺的设备了。而路由器上的两个实现网络连接的基础接口 ——WAN 口和 LAN 口,到底有什么区别?它们的功能和作用…

【Open X-Embodiment】简单数据下载与预处理

文章目录 1. RLDS Dataset2. 处理成numpy格式3. 存储桶 1. RLDS Dataset 从 Octo 里面找到数据下载的代码 rlds_dataset_mod github 按照官网代码配置环境后,修改 prepare_open_x.sh,相当于只用 gsutil 下载数据: DOWNLOAD_DIR/mnt/data…

神经网络八股(1)

1.什么是有监督学习,无监督学习 有监督学习是带有标签的,无监督学习是没有标签的,简单来说就是有监督学习的输入输出都是固定的,已知的,无监督学习输入是已知的,输出是不固定的,无监督学习是通…

达梦:开发 ODBC配置指南

目录 达梦数据库DM8 ODBC配置指南(Linux环境)ODBC一、环境准备二、核心配置步骤1. 安装unixODBC2. 配置ODBC驱动(odbcinst.ini)3. 配置数据源(odbc.ini) 三、连接测试与验证1. 使用isql工具测试2. 执行基础…

Python游戏编程之赛车游戏6-1

通过Python的pygame模块可以实现赛车游戏,如图1所示。 图1 赛车游戏 从图1中可以看出,玩家通过键盘的左右键操作蓝色汽车躲避红色汽车的撞击,每成功躲避过一辆红色汽车,则玩家得一分。当蓝色汽车被红色汽车撞击后,游戏…

【Linux网络】序列化、守护进程、应用层协议HTTP、Cookie和Session

⭐️个人主页:小羊 ⭐️所属专栏:Linux 很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~ 目录 1、序列化和反序列化2、守护进程2.1 什么是进程组?2.2 什么是会话? 3、应用层协议HTTP3.1 HTTP协议3.2 HT…

【Java消息队列】应对消息丢失、重复、顺序与积压的全面策略

应对消息丢失、重复、顺序与积压的全面策略 引言kafka消息丢失生产者消费者重复消费顺序消费消息积压生产者消费者其他RabbitMQ消息丢失生产者事务机制,保证生产者发送消息到 RabbitMQ Server发送方确认机制,保证消息能从交换机路由到指定队列保证消息在 RabbitMQ Server 中的…

Windows 上源码安装 FastGPT

FastGPT 是一个强大的 AI RAG 平台,值得我们去学习了解。与常见的 Python 体系不同,Fast GPT 采用 Node.js/Next.js 平台(对于广大 JS 开发者或前端开发者比较亲切友好),安装或部署比较简单。虽然一般情况下推荐简单的…

【HeadFirst系列之HeadFirstJava】第5天之超强力方法 —— 从战舰游戏到循环控制

编写程序:超强力方法 —— 从战舰游戏到循环控制 在《Head First Java》的第五章节中,作者通过一个简单的战舰游戏示例,深入讲解了如何编写Java程序,并重点介绍了方法和循环控制的使用。这一章节的核心思想是:通过模块…

软件单元测试的技术要求

文章目录 一、软件单元测试的概念二、测试对象三、测试目的四、进入条件五、测试内容六、测试环境七、测试实施方一、软件单元测试的概念 单元测试(Unit Testing),是指对软件中的最小可测试单元进行测试验证。单元测试是白盒测试,主要依据软件详细设计和软件代码进行,不仅…

‌挖数据平台对接DeepSeek推出一键云端部署功能:API接口驱动金融、汽车等行业智能化升级

云端部署 引言:当数据生产力遇上云端智能化 2025年2月23日,国内领先的数据服务商挖数据平台宣布与人工智能巨头DeepSeek达成战略合作,正式推出“一键云端部署”功能。这一功能以API(应用程序接口)为核心,通…

QPainter绘制3D 饼状图

先展示图片 核心代码如下&#xff1a; pie.h #ifndef Q3DPIE_H #define Q3DPIE_H#include <QtGui/QPen> #include <QtGui/QBrush>class Pie { public:double value; QBrush brush; QString description; double percentValue;QString p…

VMWare安装Debian操作系统

参考链接 https://blog.csdn.net/weixin_61536532/article/details/129778310 注意 如果希望折腾Linux&#xff0c;建议缺省使用英语。在极端情况下&#xff0c;系统可能会只能输出ASCII码&#xff0c;使用中文可能会导致无法正常打印log 本文使用VMWare WorkStation Pro&a…

Compose 常用UI组件

Compose 常用UI组件 概述Modifier 修饰符常用Modifier修饰符作用域限定Modifier Modifier 实现原理Modifier.Element链的构建链的解析 常用基础组件文字组件图片组件按钮组件选择器对话框进度条 常用布局组件线性布局帧布局 列表组件 概述 Compose 预置了很多基础组件&#xf…

基于Python+django+mysql旅游数据爬虫采集可视化分析推荐系统

2024旅游推荐系统爬虫可视化&#xff08;协同过滤算法&#xff09; 基于Pythondjangomysql旅游数据爬虫采集可视化分析推荐系统 有文档说明 部署文档 视频讲解 ✅️基于用户的协同过滤推荐算法 卖价就是标价~ 项目技术栈 Python语言、Django框架、MySQL数据库、requests网络爬虫…

R 语言科研绘图 --- 散点图-汇总

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…

3分钟idea接入deepseek

DeepSeek简介 DeepSeek 是杭州深度求索人工智能基础技术研究有限公司开发的一系列大语言模型&#xff0c;背后是知名量化资管巨头幻方量化3。它专注于开发先进的大语言模型和相关技术&#xff0c;拥有多个版本的模型&#xff0c;如 DeepSeek-LLM、DeepSeek-V2、DeepSeek-V3 等&…