深入解读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操作,适用于各种复杂的网络应用场景。

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

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

相关文章

vue2加入keep-alive后的生命周期情况

目录 1.加入keep-alive会执行哪些生命周期&#xff1f;1.activated2.deactivated 2.keep-alive是什么 &#xff1a; 缓存当前组件3.如果当前组件加入了keep-alive第一次进入这个组件会执行5个生命周期4.第二次或者第N次进去组件会执行哪些生命周期&#xff1f;1.如果当前组件加…

AIGC:引领内容创作新时代的智能引擎

随着人工智能技术的飞速发展&#xff0c;AIGC&#xff08;Artificial Intelligence Generated Content&#xff0c;人工智能生成内容&#xff09;逐渐崭露头角&#xff0c;成为推动内容创作领域变革的重要力量。作为一名程序员&#xff0c;我深感AIGC的巨大潜力和广阔前景&…

【Flink metric(3)】chunjun是如何实现脏数据管理的

文章目录 一. 基础逻辑二. DirtyManager1. 初始化2. 收集脏数据并check3. 关闭资源 三. DirtyDataCollector1. 初始化2. 收集脏数据并check3. run&#xff1a;消费脏数据4. 释放资源 四. LogDirtyDataCollector 一. 基础逻辑 脏数据管理模块的基本逻辑是&#xff1a; 当数据消…

猫咪也怕油腻?选对猫粮是关键!福派斯鲜肉猫粮守护猫咪健康

亲爱的猫友们&#xff0c;我们都知道&#xff0c;猫咪的饮食健康是每一个铲屎官都非常关心的问题。最近&#xff0c;有些猫友向我反映&#xff0c;他们给猫主子喂食的猫粮油脂比较大&#xff0c;不禁让人担心这对猫咪是否真的好。 1️⃣ 首先&#xff0c;让我们来聊聊油脂在猫粮…

Spring Boot + Vue 全栈开发,都需要哪些前端知识?

Node.js默认安装的npm包和工具的位置&#xff1a;Node.js目录\node_modules 在这个目录下你可以看见 npm目录&#xff0c;npm本身就是被NPM包管理器管理的一个工具&#xff0c;说明 Node.js已经集成了npm工具 #在命令提示符输入 npm -v 可查看当前npm版本 npm -v 二、使用n…

go多路复用功能

大家在工作中使用go语言都是因为go语言中提供方便又简介的协成吧&#xff0c;只需一个go关键字就可以开启一个协成&#xff0c;今天为大家推荐一种go实现的多路复用代码&#xff0c;大家可以参考一下呀可以下方评论留言呦 package test_7import ("fmt""testing…

如何在Ubuntu的docker部署web应用

1. 安装Docker和Docker Compose 首先&#xff0c;先介绍一下Docker与Docker Compose。 1、Docker&#xff1a; 功能&#xff1a;Docker是一个开源的容器化平台&#xff0c;用于开发、打包和运行应用程序。它利用容器技术&#xff08;如Docker容器&#xff09;来打包应用及其…

代理IP超时是什么原因?

很多用户在使用代理IP进行网络访问时&#xff0c;可能会遇到代理IP超时的情况&#xff0c;也就是代理IP的延迟过高。代理IP延迟过高会影响用户的网络体验和数据获取效率。因此&#xff0c;了解代理IP延迟过高的原因很重要。以下是导致代理IP延迟过高的一些常见原因&#xff1a;…

vue3-seamless-scroll替代源码

旧项目用的 vue3-seamless-scroll 怎么写都不生效&#xff0c;一看源码两年没更新了&#xff0c;不想调试&#xff0c;还是自己写吧&#xff0c;再不济问问GPT都会更快一点 scroll.vue <template><div class"scroll-container" ref"scrollContainerR…

FL Studio 21.2.3官方中文版重磅发布,手把手教你图文安装

FL Studio 21.2.3官方中文版重磅发布纯正简体中文支持&#xff0c;更快捷的音频剪辑及素材管理器&#xff0c;多样主题随心换&#xff01; 在数字音乐制作领域&#xff0c;FL Studio一直以其强大的功能和用户友好的界面而备受赞誉。随着技术的不断进步和音乐制作需求的日益增长…

Python高压电容导电体和水文椭圆微分

&#x1f3af;要点 &#x1f3af;二维热传导二阶偏微分方程 | &#x1f3af;调和函数和几何图曲率 | &#x1f3af;解潮汐波动方程 | &#x1f3af;解静止基态旋转球体流体运动函数 | &#x1f3af;水文空间插值 | &#x1f3af;流体流动模拟求解器 | &#x1f3af;随机算法解…

泰迪智能科技与成都文理学院人工智能与大数据学院开展校企合作交流

近日&#xff0c;在推动高等教育与产业深度融合的背景下&#xff0c;成都文理学院人工智能与大数据学院携手广东泰迪智能科技股份有限公司开展“专业建设交流会”。人工智能与大数据学院院长胡念青、院长助理陈坚、骨干教师刘超超、孙沛、赵杰、文运、胡斌、邹杰出席本次交流会…

vue项目中dom拖动排序功能实现

vue项目中拖动元素改变其顺序的功能实现 实现此功能&#xff0c;我利用的是SortableJs,其官网上直接介绍其为功能强大的js拖拽库&#xff0c;只需要简单的代码即可实现dom拖拽 1.下载 npm i sortablejs 2.引入 使用时&#xff0c;我们在那个页面中使用&#xff0c;就在该vue文…

Java CompletableFuture线程池

默认情况下 CompletableFuture 会使用公共的 ForkJoinPool 线程池&#xff0c;这个线程池默认创建的线程数是 CPU 的核数&#xff08;也可以通过 JVM option:-Djava.util.concurrent.ForkJoinPool.common.parallelism 来设置 ForkJoinPool 线程池的线程数&#xff09;。如果所有…

【progressBar-js】优雅的 前端进度条 构建!

progressBar-js JS 前端进度条小工具 您可以通过此工具来构建一个有效的工具条&#xff0c;接下来就是一个示例&#xff01; 使用示例 引入 progressBar-js 库 直接在这里将 css 和 js 文件引入进来就算是成功导入了哦&#xff01;&#xff01;&#xff01; <link href&…

文件怎么加密?电脑文件加密,分享5个实用方法

通常情况下&#xff0c;人们对手机数据的保护比对电脑数据更为重视。许多人使用指纹和密码来防止他人窥视聊天记录和照片。然而&#xff0c;电脑上的数据却常常被忽视。大多数用户仅设置了电脑登录密码&#xff0c;认为这样就足以保护电脑和其中的文件。然而如果你也是这样认为…

hex、bin、elf、s19等文件格式介绍以及格式转换

文章目录 前言一、bin文件二、hex文件数据记录格式扩展线性地址记录(HEX386)格式扩展段地址记录(HEX86)文件结束(EOF)记录三、elf文件四、S19文件五、不同格式之间转换将bin文件转换成hex文件将hex文件转换成bin文件将bin文件转换成s19文件前言 编译器或汇编器将程序的源代码(…

详解三种常用标准化 Batch Norm Layer Norm RMSNorm

参考&#xff1a; BN究竟起了什么作用&#xff1f;一个闭门造车的分析《动手学深度学习》7.5 节 深度学习中&#xff0c;归一化是常用的稳定训练的手段&#xff0c;CV 中常用 Batch Norm&#xff1b; Transformer 类模型中常用 layer norm&#xff0c;而 RMSNorm 是近期很流行…

Pyppeteer原理介绍和入门尝试

pyppeteer仓库地址&#xff1a;https://github.com/miyakogi/pyppeteer puppeteer仓库地址&#xff1a;https://github.com/search?qpuppeteer&typerepositories 因为有些网页是可以检测到是否是使用了selenium。并且selenium所谓的保护机制不允许跨域cookies保存以及登…

力扣321.拼接最大数

力扣321.拼接最大数 分成两个子问题 —— 求数组去除s个数的最大数 再归并求最大lexicographical_compare(begin1,end1,begin2,end2) 根据字典序比较两数组(字符串)大小 class Solution {public:vector<int> maxNumber(vector<int>& nums1, vector<int&g…