当前位置: 首页 > news >正文

深入解读Netty中的NIO:原理、架构与实现详解

深入解读Netty中的NIO:原理、架构与实现详解

Netty是一个基于Java的异步事件驱动网络应用框架,广泛用于构建高性能、高可扩展性的网络服务器和客户端(学习netty请参考:深入浅出Netty:高性能网络应用框架的原理与实践)。Netty的核心是基于Java NIO(Non-blocking I/O)的,因此理解Netty的实现需要先了解Java NIO的基本概念和机制。

Java NIO简介

Java NIO(New I/O)是一组新的Java I/O库,它与传统的Java I/O(即流式I/O)相比,提供了更高效的数据读写操作。NIO引入了以下几个核心概念:

  • Buffers:缓冲区是一个容器对象,包含要读写的数据。常见的缓冲区类型包括ByteBuffer、CharBuffer、IntBuffer等。
  • Channels:通道是用于读写数据的抽象,与流类似,但通道是双向的,可以同时读写。
  • Selectors:选择器用于监听多个通道的事件(如连接到达、数据可读等),实现非阻塞的多路复用I/O。

Netty中的NIO实现

Netty基于Java NIO构建,提供了更高层次的抽象和更强大的功能。以下是Netty中NIO的关键组件和工作机制的详细介绍:

1. EventLoop和EventLoopGroup

  • EventLoop:负责处理I/O操作的核心组件。每个EventLoop绑定到一个线程上,管理一个或多个Channel的所有I/O事件。
  • EventLoopGroup:管理一组EventLoop,负责线程池的管理和分配。常见实现有NioEventLoopGroup(基于Java NIO)和EpollEventLoopGroup(基于Linux epoll)。
EventLoopGroup bossGroup = new NioEventLoopGroup(1); // 用于接受连接的线程组
EventLoopGroup workerGroup = new NioEventLoopGroup(); // 用于处理连接的线程组

2. Channel和ChannelPipeline

  • Channel:Netty中的通道,表示一个到远程地址的连接,负责数据读写和连接管理。常见的实现有NioSocketChannel(基于Java NIO)和EpollSocketChannel(基于Linux epoll)。
  • ChannelPipeline:Channel的处理链,包含一系列的ChannelHandler,用于处理I/O事件和数据。事件沿着
Pipeline传播,由相应的Handler处理。
b.channel(NioServerSocketChannel.class) // 设置Channel类型.childHandler(new ChannelInitializer<SocketChannel>() {@Overridepublic void initChannel(SocketChannel ch) {ch.pipeline().addLast(new EchoServerHandler());}});

3. Selector和Reactor模型

  • Selector:Netty利用Java NIO的Selector实现I/O多路复用,监听多个通道的事件,处理非阻塞的I/O操作。
  • Reactor模型:Netty采用Reactor模式,通过单线程或多线程处理网络事件。包括单Reactor单线程、单Reactor多线程和多Reactor多线程模型。
public class NioEventLoop extends SingleThreadEventLoop {private final Selector selector;public void run() {while (!confirmShutdown()) {int selected = selector.select();processSelectedKeys();}}
}

Netty中的NIO工作流程

  • 初始化和配置:使用ServerBootstrap或Bootstrap配置服务器或客户端,设置EventLoopGroup、Channel类型和ChannelHandler。

    ServerBootstrap b = new ServerBootstrap();
    b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>() {@Overridepublic void initChannel(SocketChannel ch) {ch.pipeline().addLast(new EchoServerHandler());}});
    
  • 绑定端口并启动:绑定服务器端口并启动,等待连接到达。

    ChannelFuture f = b.bind(port).sync();
    f.channel().closeFuture().sync();
    
  • 处理连接和I/O事件

    • 接受连接:bossGroup的EventLoop监听并接受新的连接,为每个连接创建一个新的Channel。
    • 初始化Channel:通过ChannelInitializer添加一系列的ChannelHandler到ChannelPipeline中。
    • 处理I/O事件:workerGroup的EventLoop处理Channel的I/O事件,事件沿Pipeline传播,由相应的Handler处理。
  • 异步操作和回调:使用Future和Promise处理异步操作的结果,通过回调方式处理操作完成后的逻辑。

示例代码详解

  • EchoServerHandler

    public class EchoServerHandler extends ChannelInboundHandlerAdapter {@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) {// 将接收到的消息写回客户端ctx.write(msg);}@Overridepublic void channelReadComplete(ChannelHandlerContext ctx) {// 将消息刷新到远程节点ctx.flush();}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {// 发生异常时关闭连接cause.printStackTrace();ctx.close();}
    }
    
  • EchoClientHandler

    public class EchoClientHandler extends ChannelInboundHandlerAdapter {@Overridepublic void channelActive(ChannelHandlerContext ctx) {// 连接建立后发送消息ctx.writeAndFlush(Unpooled.copiedBuffer("Hello, Netty!", CharsetUtil.UTF_8));}@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) {// 接收到服务器的响应System.out.println("Client received: " + ((ByteBuf) msg).toString(CharsetUtil.UTF_8));}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {// 发生异常时关闭连接cause.printStackTrace();ctx.close();}
    }
    

总结

Netty通过其灵活的架构和高效的I/O处理机制,基于Java NIO提供了强大的网络编程能力。理解Netty中的NIO实现和工作原理,对于构建高性能、高并发的网络应用至关重要。Netty通过EventLoop、Channel、Pipeline、Selector等核心组件,实现了非阻塞、事件驱动的I/O操作,适用于各种复杂的网络应用场景。

相关文章:

深入解读Netty中的NIO:原理、架构与实现详解

深入解读Netty中的NIO&#xff1a;原理、架构与实现详解 Netty是一个基于Java的异步事件驱动网络应用框架&#xff0c;广泛用于构建高性能、高可扩展性的网络服务器和客户端&#xff08;学习netty请参考&#xff1a;深入浅出Netty&#xff1a;高性能网络应用框架的原理与实践&…...

Vim和Nano简介

**Vim**&#xff1a; - Vim 是一个文本编辑器&#xff0c;它是 Vi 编辑器的一个改进版本&#xff0c;Vi 编辑器最初由 Bill Joy 在1976年为 BSD Unix 开发。 - Vim 由 Bram Moolenaar 开发&#xff0c;其第一个版本在1991年发布。Vim 的设计理念是“持继改进”&#xff0c;它的…...

mysql的information_schema浅析

information_schema 是 MySQL 中的一个虚拟数据库&#xff0c;它包含了关于 MySQL 服务器的所有元数据。 information_schema 作用 元数据管理&#xff1a;提供关于数据库、表、列、索引、权限等的信息。 性能优化&#xff1a;帮助了解数据库结构和索引使用情况&#xff0c;便…...

力扣爆刷第153天之TOP100五连刷26-30(接雨水、环形链表、最长上升子序列)

力扣爆刷第153天之TOP100五连刷26-30&#xff08;接雨水、环形链表、最长上升子序列&#xff09; 文章目录 力扣爆刷第153天之TOP100五连刷26-30&#xff08;接雨水、环形链表、最长上升子序列&#xff09;一、300. 最长递增子序列二、415. 字符串相加三、143. 重排链表四、42.…...

【Linux】—Apache Hive 安装部署

文章目录 前言认识Metadata认识Metastoremetastore三种配置方式 一、安装前准备二、下载hive-3.1.2安装包三、下载完成后&#xff0c;通过xftp6上传到Linux服务器上四、解压Hive安装包五、配置Hive六、内嵌模型安装—Hive元数据配置到Derby七、本地模式安装—Hive元数据配置到M…...

组装盒示范程序

代码; #include <gtk-2.0/gtk/gtk.h> #include <glib-2.0/glib.h> #include <stdio.h>int main(int argc, char *argv[]) {gtk_init(&argc, &argv);GtkWidget *window;window gtk_window_new(GTK_WINDOW_TOPLEVEL);gtk_window_set_title(GTK_WINDO…...

推荐一款AI修图工具,支持AI去水印,AI重绘,AI抠图...

不知道大家有没有这样的一个痛点&#xff0c;发现了一张不错的“素材”&#xff0c; 但是有水印&#xff0c;因此不能采用&#xff0c;但找来找去&#xff0c;还是觉得初见的那个素材不错&#xff0c;怎么办&#xff1f; 自己先办法呗。 二师兄发现了一款功能强大的AI修图工具…...

2024广东省职业技能大赛云计算赛项实战——容器化部署Nginx

容器化部署Nginx 前言 编写Dockerfile文件构建nginx镜像&#xff0c;要求基于centos完成Nginx服务的安装和配置&#xff0c;并设置服务开机自启。 编写Dockerfile构建镜像erp-nginx:v1.0&#xff0c;要求使用centos7.9.2009镜像作为基础镜像&#xff0c;完成Nginx服务的安装&…...

压缩pdf文件大小在线,在线免费压缩pdf

在现在办公中&#xff0c;PDF文档已经成为我们日常工作中不可或缺的一部分。然而&#xff0c;随着文档内容的不断丰富&#xff0c;PDF文件的大小也逐渐增大&#xff0c;这不仅占用了大量的存储空间&#xff0c;而且在传输和共享时也显得尤为不便。所以有时候我们需要把pdf压缩小…...

薄冰英语语法学习--名词1

我用来教我自己3岁的小孩的。 有特殊的情况&#xff0c;暂时先不用管&#xff0c;3岁小孩&#xff0c;只用全部按非特殊情况算就ok了&#xff0c;以后长大了&#xff0c;遇到问题了&#xff0c;再微调一下。先解决百分之90的问题。 一般的复数&#xff0c;直接加s 特殊的词尾…...

oracle12c到19c adg搭建(六)切换后12c备库服务器安装19c软件在19c主库升级数据字典后尝试同步

一、安装19c软件 参考文章oracle12c到19c adg搭建&#xff08;三&#xff09;oracle19c数据库软件安装 二、原主库尝试通过19c软件启动数据库 2.1复制12c的相关参数文件和密码文件到19c目录 注意:密码文件需要从已切换主库19c传过来 [oracleo12u19p ~]$ cd /u01/app/oracle…...

Scope XY Project的使用

1.Scope XY Project的功能介绍与使用方法 添加监控变量 绘制成一个三角形 XY进行对调操作 修改XY轴的比例修改显示输出 2.Cursor的使用方法 游标线的添加测量 3.Reporting功能的使用方法 到处对应的报表数据 添加对应的报告数据...

Pytorch Geometric(PyG)入门

PyG (PyTorch Geometric) 是建立在 PyTorch 基础上的一个库&#xff0c;用于轻松编写和训练图形神经网络 (GNN)&#xff0c;适用于与结构化数据相关的各种应用。官方文档 Install PyG PyG适用于python3.8-3.12 一般使用场景&#xff1a;pip install torch_geometric 或conda …...

大模型KV Cache节省神器MLA学习笔记(包含推理时的矩阵吸收分析)

首先&#xff0c;本文回顾了MHA的计算方式以及KV Cache的原理&#xff0c;然后深入到了DeepSeek V2的MLA的原理介绍&#xff0c;同时对MLA节省的KV Cache比例做了详细的计算解读。接着&#xff0c;带着对原理的理解理清了HuggingFace MLA的全部实现&#xff0c;每行代码都去对应…...

项目中eventbus和rabbitmq配置后,不起作用

如下&#xff1a;配置了baseService层和SupplyDemand层得RabbitMQ和EventBus 但是在执行订阅事件时&#xff0c;发送得消息在base项目中没有执行&#xff0c;后来发现是虚拟机使用得不是一个&#xff0c;即上图中得EventBus下得VirtualHost&#xff0c;修改成一直就可以了...

文库小程序搭建部署:实现资源共享正向反馈

文档库相信大家应该不陌生&#xff0c;日常我们的工作模板、会议模板、求职时的简历模板、教育界的教学模板等来源方式都出自于文档库&#xff0c;随着互联网的发展和工作需求&#xff0c;文档模板开启了新型的知识变现新途径&#xff0c;通过文库小程序&#xff0c;我们不仅能…...

ONLYOFFICE 桌面编辑器8.1---一个高效且强大的办公软件

软件介绍 ONLYOFFICE 桌面编辑器经过不断的更新换代现在迎来了&#xff0c;功能更加强大的ONLYOFFICE 桌面编辑器8.1是一个功能强大的办公套件&#xff0c;专为多平台设计&#xff0c;包括Windows、Linux和macOS。它提供了一套全面的办公工具&#xff0c;包括文档处理、电子表…...

QThread 与QObject::moveToThread利用Qt事件循环在子线程执行多个函数

1. QThread的两种用法 第一种用法就是继承QThread&#xff0c;然后覆写 virtual void run()&#xff0c; 这种用法的缺点是不能利用信号槽机制。 第二种用法就是创建一个线程&#xff0c;创建一个对象&#xff0c;再将对象moveToThread, 这种可以充分利用信号槽机制&#xff…...

6-2 归并排序

6-2 归并排序 分数 10 全屏浏览 切换布局 作者 软件工程DS&A课程组 单位 燕山大学 以下代码采用分而治之算法实现归并排序。请补充函数mergesort&#xff08;&#xff09;的代码。提示&#xff1a;mergesort&#xff08;&#xff09;函数可用递归实现&#xff0c;其中参…...

Java NIO(一) 概述

NIO主要用于以少量线程来管理多个网络连接&#xff0c;处理其上的读写等事件。在大量连接情况下&#xff0c;不管是效率还是空间占用都要优于传统的BIO。 Java NIO 由以下几个核心部分组成&#xff1a; Channel Buffer Selector Selector 如果你的应用打开了多个连接&#x…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程&#xff0c;并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令&#xff0c;把数据流转换成Message&#xff0c;状态转变流程是&#xff1a;State::Created 》 St…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器&#xff08;ADC&#xff09;&#xff0c;支持8kHz~96kHz采样率&#xff0c;集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器&#xff0c;适用于高保真音频采集场景。 2. 核心特性 高精度&#xff1a;24位分辨率&#xff0c…...

【Go语言基础【12】】指针:声明、取地址、解引用

文章目录 零、概述&#xff1a;指针 vs. 引用&#xff08;类比其他语言&#xff09;一、指针基础概念二、指针声明与初始化三、指针操作符1. &&#xff1a;取地址&#xff08;拿到内存地址&#xff09;2. *&#xff1a;解引用&#xff08;拿到值&#xff09; 四、空指针&am…...

MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用

文章目录 一、背景知识&#xff1a;什么是 B-Tree 和 BTree&#xff1f; B-Tree&#xff08;平衡多路查找树&#xff09; BTree&#xff08;B-Tree 的变种&#xff09; 二、结构对比&#xff1a;一张图看懂 三、为什么 MySQL InnoDB 选择 BTree&#xff1f; 1. 范围查询更快 2…...