Netty 模型理解

news2024/10/7 2:19:49

参考文章 1
参考文章 2

官网API文档

在这里插入图片描述

Reactor模型

在这里插入图片描述

Netty模型

Netty主要基于主从Reactor多线程模型进行了一定的修改,该模型包括以下几个组件:

  1. MainReactor(主Reactor):负责处理客户端的连接请求。它监听服务器上的端口,接收客户端的连接请求,并将请求分发给SubReactor进行处理。

  2. SubReactor(从Reactor):负责处理连接成功后的通道的IO读写请求。每个SubReactor负责管理一组通道,它们使用多路复用技术(如Java NIO)来监听通道上的事件,例如可读、可写等事件。一般情况下,每个SubReactor都对应一个线程。

  3. Worker Threads(工作线程):负责处理非IO请求,即具体的业务逻辑处理。当有非IO请求需要处理时,这些任务会被写入一个队列中,等待工作线程来处理。工作线程可以是线程池中的线程,也可以是其他类型的线程。
    在这里插入图片描述

模块组件

在这里插入图片描述

  1. BootstrapServerBootstrap: 在Netty中,BootstrapServerBootstrap是用于启动和配置Netty应用程序的引导类。Bootstrap类是用于客户端程序的启动引导类,ServerBootstrap类是服务端启动引导类。
  2. NioEventLoopGroupNioEventLoopGroup是Netty中用于管理NioEventLoop的组件,它是一个线程池,包含多个NioEventLoop实例,它对应着主从Reactor多线程模型中ReactorNioEventLoopGroup负责创建、管理和分配NioEventLoop,处理异常情况,并提供优雅关闭的机制。它是Netty实现高性能的重要组件之一。
  3. NioEventLoopNioEventLoop是Netty中的核心组件,负责处理I/O事件和执行任务。它使用Selector来监听和处理注册在其上的Channel的I/O事件,同时支持异步提交和执行任务。NioEventLoop还管理定时任务和处理异常情况,是实现高性能和事件驱动的重要组成部分。

什么是Selector

  1. Selector:Netty基于Selector对象实现了I/O多路复用。通过将多个Channel注册到一个Selector中,并使用一个线程来监听和处理这些Channel的事件,可以高效地管理多个ChannelSelector会自动不断地查询这些注册的Channel,以检查它们是否有已就绪的I/O事件。

  2. Channel:在Netty中,Channel表示一个开放的网络连接,可以用于读取、写入和处理网络数据。它是网络通信的基本单元,负责处理底层的数据传输和事件通知。

    • NioSocketChannel:异步的客户端 TCP Socket 连接
    • NioServerSocketChannel:异步的服务器端 TCP Socket 连接
    • NioDatagramChannel:异步的 UDP 连接
    • NioSctpChannel:异步的客户端 Sctp 连接
    • NioSctpServerChannel:异步的 Sctp 服务器端连接
  3. ChannelHandler:在Netty中,ChannelHandler是一个接口,用于处理I/O事件或拦截I/O操作,并将其转发到ChannelPipeline中的下一个处理程序。ChannelHandler是Netty的核心组件之一,它负责处理各种事件,如连接建立、数据读写、异常发生等。

    • ChannelInboundHandler:用于处理入站I/O事件
    • ChannelOutboundHandler:用于处理出站I/O操作
  4. ChannelHandlerContextChannelHandlerContext保存了与特定Channel相关的所有上下文信息,同时关联一个ChannelHandler对象,并提供了访问ChannelChannelHandlerChannelPipeline的方法。

  5. ChannelPipline: 它是一个保存ChannelHandler的列表,用于处理或拦截Channel的入站事件和出站操作。 ChannelPipeline实现了一种高级形式的拦截过滤器模式,使用户可以完全控制事件的处理方式以及Channel中各个的ChannelHandler如何相互交互。
    在 Netty 中每个 Channel 都有且仅有一个 ChannelPipeline 与之对应, 它们的组成关系如下:
    在这里插入图片描述
    一个Channel包含了一个ChannelPipeline,而ChannelPipeline中维护了一个由ChannelHandlerContext组成的双向链表。入站事件和出站事件在这个双向链表中进行传递,入站事件从链表的head往后传递到最后一个入站的ChannelHandler,出站事件从链表的tail往前传递到最前一个出站的ChannelHandler,两种类型的ChannelHandler互不干扰。通过这种设计,ChannelPipeline实现了事件的顺序传递和处理。

  6. FutureChannelFuture: Netty中的IO操作都是异步的,这意味着在发起一个IO操作后,无需等待其完成就可以继续执行后续的代码逻辑。为了获取操作的执行结果或者在操作完成时得到通知,Netty提供了FutureChannelFuture

实例代码

服务端

public class MyServer {
    public static void main(String[] args) throws Exception {
        //创建两个线程组 boosGroup、workerGroup
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            //创建服务端的启动对象,设置参数
            ServerBootstrap bootstrap = new ServerBootstrap();
            //设置两个线程组boosGroup和workerGroup
            bootstrap.group(bossGroup, workerGroup)
                //设置服务端通道实现类型    
                .channel(NioServerSocketChannel.class)
                //设置线程队列得到连接个数    
                .option(ChannelOption.SO_BACKLOG, 128)
                //设置保持活动连接状态    
                .childOption(ChannelOption.SO_KEEPALIVE, true)
                //使用匿名内部类的形式初始化通道对象    
                .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            //给pipeline管道设置处理器
                            socketChannel.pipeline().addLast(new MyServerHandler());
                        }
                    });//给workerGroup的EventLoop对应的管道设置处理器
            System.out.println("java技术爱好者的服务端已经准备就绪...");
            //绑定端口号,启动服务端
            ChannelFuture channelFuture = bootstrap.bind(6666).sync();
            //对关闭通道进行监听
            channelFuture.channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}
/**
 * 自定义的Handler需要继承Netty规定好的HandlerAdapter
 * 才能被Netty框架所关联,有点类似SpringMVC的适配器模式
 **/
public class MyServerHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        //获取客户端发送过来的消息
        ByteBuf byteBuf = (ByteBuf) msg;
        System.out.println("收到客户端" + ctx.channel().remoteAddress() + "发送的消息:" + byteBuf.toString(CharsetUtil.UTF_8));
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        //发送消息给客户端
        ctx.writeAndFlush(Unpooled.copiedBuffer("服务端已收到消息,并给你发送一个问号?", CharsetUtil.UTF_8));
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        //发生异常,关闭通道
        ctx.close();
    }
}

客户端

public class MyClient {

    public static void main(String[] args) throws Exception {
        NioEventLoopGroup eventExecutors = new NioEventLoopGroup();
        try {
            //创建bootstrap对象,配置参数
            Bootstrap bootstrap = new Bootstrap();
            //设置线程组
            bootstrap.group(eventExecutors)
                //设置客户端的通道实现类型    
                .channel(NioSocketChannel.class)
                //使用匿名内部类初始化通道
                .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            //添加客户端通道的处理器
                            ch.pipeline().addLast(new MyClientHandler());
                        }
                    });
            System.out.println("客户端准备就绪,随时可以起飞~");
            //连接服务端
            ChannelFuture channelFuture = bootstrap.connect("127.0.0.1", 6666).sync();
            //对通道关闭进行监听
            channelFuture.channel().closeFuture().sync();
        } finally {
            //关闭线程组
            eventExecutors.shutdownGracefully();
        }
    }
}
public class MyClientHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        //发送消息到服务端
        ctx.writeAndFlush(Unpooled.copiedBuffer("歪比巴卜~茉莉~Are you good~马来西亚~", CharsetUtil.UTF_8));
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        //接收服务端发送过来的消息
        ByteBuf byteBuf = (ByteBuf) msg;
        System.out.println("收到服务端" + ctx.channel().remoteAddress() + "的消息:" + byteBuf.toString(CharsetUtil.UTF_8));
    }
}

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

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

相关文章

【洛谷 P1636】Einstein学画画 题解(图论+欧拉通路)

Einstein学画画 题目描述 Einstein 学起了画画。 此人比较懒~~&#xff0c;他希望用最少的笔画画出一张画…… 给定一个无向图&#xff0c;包含 n n n 个顶点&#xff08;编号 1 ∼ n 1 \sim n 1∼n&#xff09;&#xff0c; m m m 条边&#xff0c;求最少用多少笔可以画…

京东采销面对面,洞悉行业新趋势 京东3C数码生态大会在武汉圆满举行

为促进湖北省3C数码产业发展&#xff0c;本地企业降本增效、促进行业交流、充分发挥京东集团全链路生态服务能力&#xff0c;支持地方3C特色产业提质增量。2023年11月23日&#xff0c;由京东零售、京东物流主办&#xff0c;湖北省电子商务行业协会联合协办的“聚力共赢、携手共…

《C++ Primer》第10章 算法(一)

参考资料&#xff1a; 《C Primer》第5版《C Primer 习题集》第5版 10.1 概述&#xff08;P336&#xff09; 大多数算法定义在头文件 algorithm 中&#xff0c;头文件 numeric 中也定义了一组数值泛型算法。 一般情况下&#xff0c;算法不直接操作容器&#xff0c;而是通过…

SOLIDWORKS 2024新功能之CAM篇

SOLIDWORKS 2024 新功能 CAM篇目录概述 • 附加探测周期参数 • 反转切割的固定循环螺纹加工 • 包含装配体的零件的正确进给/速度数据 • Heidenhain 探测类型 • 2.5 轴特征向导中岛屿的终止条件 • 链接轮廓铣削操作的切入引导和切出引导参数 • 螺纹铣削操作的最小孔…

SpringCloud 微服务全栈体系(十七)

第十一章 分布式搜索引擎 elasticsearch 七、搜索结果处理 搜索的结果可以按照用户指定的方式去处理或展示。 1. 排序 elasticsearch 默认是根据相关度算分&#xff08;_score&#xff09;来排序&#xff0c;但是也支持自定义方式对搜索结果排序。可以排序字段类型有&#…

标题导航点击导航滑动到指定位置滑动到指定位置选中对应导航vue3

菜单导航栏点击导航滑动到指定位置&滑动到指定位置选中对应导航 效果 实现 话不多说直接上代码&#xff0c;有用素质三连(点赞、评论、加关注) import { defineComponent, onBeforeUnmount, onMounted, reactive, ref } from "vue"; import { map } from &quo…

家用小型洗衣机哪款性价比高?口碑最好迷你洗衣机排行榜

由于我们的内衣、内裤和袜子等等贴身小件衣物的清洁频率比一般的衣物要高。而且&#xff0c;如果我们人工手洗的话&#xff0c;不仅会大大浪费了我们的时间&#xff0c;而且还不能进行对这些贴身的以为进行深层消毒和除菌。这种情况下&#xff0c;就得需要一台专门用于清洗内衣…

怎么去掉视频水印?分享三种视频去水印技巧,轻松搞定!

怎么去掉视频水印&#xff1f;在分享视频时&#xff0c;我们常常会遇到因为水印而影响观感的问题&#xff0c;因此&#xff0c;掌握有效的去水印方法显得尤为重要&#xff0c;随着技术的进步&#xff0c;现在有多种方法可以帮助我们去除视频中的水印。 接下来分享三种简单且有效…

【算法挨揍日记】day33——1027. 最长等差数列、446. 等差数列划分 II - 子序列

1027. 最长等差数列 1027. 最长等差数列 题目描述&#xff1a; 给你一个整数数组 nums&#xff0c;返回 nums 中最长等差子序列的长度。 回想一下&#xff0c;nums 的子序列是一个列表 nums[i1], nums[i2], ..., nums[ik] &#xff0c;且 0 < i1 < i2 < ... < …

两个链表的第一个公共节点(相交链表),剑指offer,力扣

目录 题目地址&#xff1a; 题目&#xff1a; 我们直接看题解吧&#xff1a; 解题方法&#xff1a; 审题目事例提示&#xff1a; 解题思路&#xff08;双指针&#xff09;&#xff1a; 具体思路流程&#xff1a; 代码实现&#xff1a; 算法思路补充证明&#xff1a; 力扣题目地…

Doris中的物化视图-查询(十九)

物化视图创建完成后&#xff0c;用户的查询会根据规则自动匹配到最优的物化视图。 比如我们有一张销售记录明细表&#xff0c;并且在这个明细表上创建了三张物化视图。一个存储了不同时间不同销售员的售卖量&#xff0c;一个存储了不同时间不同门店的销售量&#xff0c;以及每…

图数据库HugeGraph:HugeGraph-Hubble基于Web的可视化图管理初体验

原创/朱季谦 一、HugeGraph-Hubble简介 关于HugeGraph&#xff0c;官方资料是这样介绍的&#xff0c;它是一款易用、高效、通用的开源图数据库系统&#xff08;Graph Database&#xff09;&#xff0c; 实现了 Apache TinkerPop3 框架及完全兼容 Gremlin 查询语言&#xff0c…

2023.11.23 云服务器实现 Spring Boot 项目文件上传并访问

环境介绍 云服务器&#xff1a;京东云云服务器系统&#xff1a; CentOS 7.9JDK 版本&#xff1a;1.8Spring Boot 版本&#xff1a;2.7.17 具体步骤 步骤一 首先我们得先创建一个 Spring Boot 项目 创建如下目录结构 关于如何创建一个 Spring Boot 项目 请点击下方链接详细了解 …

vs2015如何远程启动程序来进行调试

vs远程调试的方式有两种&#xff0c;远程启动方式和附加进程方式。   一般来说&#xff0c;咱们使用vs调试代码时&#xff0c;直接附加进程即可&#xff0c;但某些时候附加进程方式无法命中断点。比如我们想调试的C代码&#xff0c;但是调试的入口程序是C#程序&#xff0c;如…

JavaScript实现动态背景颜色

JavaScript实现动态背景颜色 前言实现过程HTML实现过程CSS实现过程JS实现过程全部源码 前言 本文主要讲解JavaScript如何实现动态背景颜色&#xff0c;可以根据颜色选择器选择的颜色而实时更新到背景中&#xff0c;如下图所示。 当我们在颜色选择器中改变颜色时&#xff0c;会…

2023年10月纸巾市场分析(京东天猫淘宝平台纸巾品类数据采集)

双十一大促期间&#xff0c;刚需品的纸巾是必囤商品之一。今年双十一&#xff0c;京东数据显示&#xff0c;10月23日至29日&#xff0c;清洁纸品成交额同比增长40%&#xff0c;由此也拉动了10月纸巾市场的销售。 鲸参谋数据显示&#xff0c;今年10月&#xff0c;京东平台纸巾市…

Django JSONField/HStoreField SQL注入漏洞(CVE-2019-14234)

漏洞描述 Django 于2019年8月1日 日发布了安全更新&#xff0c;修复了 JSONField 和 HStoreField 两个模型字段的 SQL 注入漏洞。 参考链接&#xff1a; Django security releases issued: 2.2.4, 2.1.11 and 1.11.23 | Weblog | DjangoDjango JSONField SQL注入漏洞&#x…

java设计模式学习之【工厂模式】

文章目录 引言工厂方法模式简介定义与用途&#xff1a;实现方式&#xff1a; 使用场景优势与劣势工厂模式在spring中的应用电费计算示例&#xff08;简单工厂模式&#xff09;改善为方法工厂模式代码地址 引言 在软件开发的世界中&#xff0c;对象的创建可能是一个复杂且重复的…

NX二次开发UF_CSYS_edit_matrix_of_object 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CSYS_edit_matrix_of_object Defined in: uf_csys.h int UF_CSYS_edit_matrix_of_object(tag_t object_id, tag_t matrix_id ) overview 概述 Updates the specified coordinat…

杰发科技AC7801——ADC简单理解

前言 7801资料读起来不是很好理解&#xff0c;大概率是之前MTK的大佬写的。在此以简单的方式进行描述。我们做一个简单的规则组软件触发Demo。因为规则组通道只有一个数据寄存器&#xff0c;因此还需要用上DMA方式搬运数据到内存。 AC7801的ADC简介 7801的ADC是一种 12 位 逐…