Netty 模型理解

参考文章 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、workerGroupEventLoopGroup bossGroup = new NioEventLoopGroup();EventLoopGroup workerGroup = new NioEventLoopGroup();try {//创建服务端的启动对象,设置参数ServerBootstrap bootstrap = new ServerBootstrap();//设置两个线程组boosGroup和workerGroupbootstrap.group(bossGroup, workerGroup)//设置服务端通道实现类型    .channel(NioServerSocketChannel.class)//设置线程队列得到连接个数    .option(ChannelOption.SO_BACKLOG, 128)//设置保持活动连接状态    .childOption(ChannelOption.SO_KEEPALIVE, true)//使用匿名内部类的形式初始化通道对象    .childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected 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 {@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {//获取客户端发送过来的消息ByteBuf byteBuf = (ByteBuf) msg;System.out.println("收到客户端" + ctx.channel().remoteAddress() + "发送的消息:" + byteBuf.toString(CharsetUtil.UTF_8));}@Overridepublic void channelReadComplete(ChannelHandlerContext ctx) throws Exception {//发送消息给客户端ctx.writeAndFlush(Unpooled.copiedBuffer("服务端已收到消息,并给你发送一个问号?", CharsetUtil.UTF_8));}@Overridepublic 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>() {@Overrideprotected 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 {@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {//发送消息到服务端ctx.writeAndFlush(Unpooled.copiedBuffer("歪比巴卜~茉莉~Are you good~马来西亚~", CharsetUtil.UTF_8));}@Overridepublic 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.hqwc.cn/news/214719.html

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

相关文章

在Linux上搭建JavaWeb项目运行环境

文章目录 安装JDK安装Tomcat安装数据库 安装JDK 安装Oracle官方的JDK比较麻烦&#xff0c;我们在此处选择安装开源社区维护的openjdk。他们俩的差别不大且兼容。 安装Tomcat 我们把本地下载好的 tomcat.zip 包拖到Linux页面上&#xff0c;让Linux也有一个zip包&#xff0c;再…

CVE-2023-22515:Atlassian Confluence权限提升漏洞复现 [附POC]

文章目录 Atlassian Confluence权限提升(CVE-2023-22515)漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 0x06 修复建议 Atlassian Confluence权限提升(CVE-2023-22515)漏洞复现 [附POC] 0x01 前言 免责声明&…

【数据分享】2022年我国省市县三级的雏鹰企业数量(免费获取/Excel/Shp格式)

企业是经济活动的参与主体。一个城市的企业数量决定了这个城市的经济发展水平&#xff01;比如一个城市的金融企业较多&#xff0c;那这个城市的金融产业肯定比较发达&#xff1b;一个城市的制造业企业较多&#xff0c;那这个城市的制造业肯定比较发达。 之前我们给大家分享了…

葡萄酒如何按颜色进行分类?

在世界众多的葡萄酒中&#xff0c;葡萄酒的颜色受品种、产区和酿造方法影响&#xff0c;可谓多种多样&#xff0c;用万紫千红形容也不为过。为了更好辨识&#xff0c;一般葡萄酒根据不同颜色&#xff0c;分为三个大类即&#xff1a;红葡萄酒、白葡萄酒、桃红葡萄酒。 红葡萄酒…

基于WEB的网上购物系统的设计与实现(附:源码 论文 sql文件)

摘 要 随着计算机网络技术的飞速发展和人们生活节奏的不断加快&#xff0c;电子商务技术已经逐渐融入了人们的日常生活当中&#xff0c;网上商城作为电子商务最普遍的一种形式&#xff0c;已被大众逐渐接受。因此开发一个网上商城系统&#xff0c;适合当今形势&#xff0c;更加…

10月,1Panel开源面板项目收到了这些评论

2023年10月20日&#xff0c;1Panel开源面板&#xff08;https://github.com/1Panel-dev&#xff09;项目发布了题为《9月&#xff0c;1Panel开源面板收到了这些评论》的社区评论合集。在该文章的评论区&#xff0c;很多社区用户跟帖发表了自己对1Panel开源项目的使用感受和意见…

从 RBAC 到 NGAC ,企业如何实现自动化权限管理?

随着各领域加快向数字化、移动化、互联网化的发展&#xff0c;企业信息环境变得庞大复杂&#xff0c;身份和权限管理面临巨大的挑战。为了满足身份管理法规要求并管理风险&#xff0c;企业必须清点、分析和管理用户的访问权限。如今&#xff0c;越来越多的员工采用移动设备进行…

Spring Web MVC

目录 一.简介 二.建立连接&#xff08;客户端和服务器&#xff09; 三.请求 1.传递单个参数 2.传递多个参数 3.对象 4.数组/集合 5.JSON 6.URL参数 7.上传文件 8.获取cookie和session &#xff08;1&#xff09;获取cookie &#xff08;2&#xff09;获取session …

Ubuntu 设置Nginx开机自启

1.建立自启动服务文件 vim /usr/lib/systemd/system/nginx.service Descriptionnginx - high performance web server Afternetwork.target remote-fs.target nss-lookup.target [Service] Typeforking ExecStart/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx…

三菱PLC定时中断应用编程(计数器+比较器)

三菱PLC如何开启定时中断可以查看下面文章链接: PLC定时中断程序应用注意事项(西门子三菱信捷)_plc设置断点之后会怎样_RXXW_Dor的博客-CSDN博客文章浏览阅读2.5k次,点赞5次,收藏6次。首先我们了解下什么是中断。中断(打断的意思),在PLC执行当前程序时,由于系统出现了…

6个免费在线工具推荐

NSDT 三维场景建模工具GLTF/GLB在线编辑器Three.js AI自动纹理化开发包YOLO 虚幻合成数据生成器3D模型在线转换三维模型预览图生成器 1、NSDT 三维场景建模 访问地址&#xff1a;NSDT 编辑器 基于WebGL技术&#xff0c;依托丰富的模型资产库&#xff0c;通过拖拽式的操作&…

pytest-html测试报告这样写,某易测开都直呼:大哥受小弟一拜

在 pytest 中提供了生成html格式测试报告的插件 pytest-html 安装 安装命令如下&#xff1a; pip install pytest-html使用 我们已经知道执行用例的两种方式&#xff0c;pytest.main()执行和命令行执行&#xff0c;而要使用pytest-html生成报告&#xff0c;只需要在执行时加…