Netty—网络的高层建筑
Netty什么?
高性能、可扩展、异步事件驱动的网络应用程序框架,其极大的简化了TCP,UDP客户端和服务器端开发等网络编程,下面是最近学习的一些总结,希望有错误的大家提出来一起进步。
Netty架构—过程分析
- Netty缓存区buffer
- 通道channel、pipeline
- selector机制的使用
说明:这几个是比较重要的关键字,首先需要记住它们进行下面的阅读。
- 线程模型
线程模型的不同,对性能的影响也是非常大的
事件驱动模型
通常我们设计一个事件处理模型的程序有两种思路:
第一种:轮询方式,线程不断的询问相关发生源有没有发生事件,有发生事件就调用事件逻辑处理
第二种:事件驱动方式:发生事件,主线程把请求事件放入等待事件队列Reactor线程池,另外任务线程不断循环消费者事件(请求任务),调用事件对应的处理逻辑处理事件,事件驱动也被称为消息通知方式,本质就是观察者的Reactor线程模式,模型如下:
基本组件介绍:
1.事件队列 :储存待处理的事件(EventLoop轮询的请求队列)
2.事件分发器:把不同事件分配给不同的业务处理逻辑单元(Dispatcher)
3.事件通道: 事件分发器与事件处理器之间的连接
4.事件处理器 处理分发器分发过来的事件
说明:请求事件进入队列—>通过轮询事件分发器—>进过事件通道—>事件处理器
- 取决于Reactor的数据以及handler的线程数量的不同,Reactor有三种线程模式;
1.单Reactor单线程模型:
2.单Reactor 多线程模型:
3.主从Reacor多线程模型
说明: Reactor 模式也叫 Dispatcher 模式,即 I/O 多路复用统一监听事件,收到事件后分发(Dispatch 给某进程)分handler处理器进行处理。
- 2 个关键组成:
- Reactor,Reactor 在一个单独的线程中运行,负责监听和分发事件,分发给适当的处理程序来对 IO 事件做出反应。
- Handlers,处理程序执行 I/O 事件要完成的实际事件,一般是非阻塞操作。
Reactor模型:
可以这样理解,Reactor 就是一个执行 while (true) { selector.select(); …} 循环的线程,会源源不断的产生新的事件,称作反应堆很贴切。
- 主从Reacor多线程模型详解:
- MainReactor 负责客户端的连接请求,并将请求转交给 SubReactor。
- SubReactor 负责相应通道的 IO 读写请求。
- 非 IO 请求(具体逻辑处理)的任务则会直接写入队列,等待 worker threads 进行处理。
特别说明的是:虽然 Netty 的线程模型基于主从 Reactor 多线程,借用了 MainReactor 和 SubReactor 的结构。但是实际实现上 SubReactor 和 Worker 线程在同一个线程池中,都是线程。
异步处理:
Netty进行异步操作时,比如bind,write,Connect等时,会返回一个channelFuture对象,调用者可以通过返回的对象channelFuture的状态,注册监听函数来执行完成后的操作具体future的方法有:
- isDone,表示完成
- isSuccess表示成功
- getCause 获取操作失败的原因
- isCancelled判断当前操作是否被取消
说明:通过 addListener 方法来注册监听器,当操作已完成(isDone 方法返回完成),将会通知指定的监听器;如果 Future 对象已完成,则理解通知指定的监听器。
Netty架构—组件分析
- 以下几方面分析Netty的架构设计
- 模块组件:
- bootStrap:一个netty程序通常由bootstrap开始,配置整个netty,串联整个组件,客户端引导类
- selector:
selector对象实现I/O多路复用技术,通过selector一个线程可以监听多个channel事件
向 Selector 中注册 Channel ,Selector 内部的机制就可以自动不断地查询(Select) 这些注册的 Channel 是否有已就绪的 I/O 事件,这样程序就可以很简单地使用一个线程高效地管理多个 Channel 。
serverBoorStrap:服务器端引导类 - NioEnventLoop:
NioEnvenLoop维护一个线程和任务队列,可以异步提交任务,启动线程时调用NioEnventLoop的run方法,实行I/O或者非I/O
I/O 任务,即 selectionKey 中 ready 的事件,如 accept、connect、read、write 等,由 processSelectedKeys 方法触发。
非 IO 任务,添加到 taskQueue 中的任务,如 register0、bind0 等任务,由 runAllTasks 方法触发。
两种任务的执行时间比由变量 ioRatio 控制,默认为 50,则表示允许非 IO 任务执行的时间与 IO 任务的执行时间相等 - NioEventLoopGroup
主要EnventLoop的周期,可以理解为一个线程池,内部维护了一组线程,每个线程NioEventLoop负责处理多个channel上的事件,而一个channel对应一个线程 - Channel:
不同协议、不同的阻塞类型的连接都有不同的 Channel 类型与之对应下面是一些常用的 Channel 类型:
- NioSocketChannel,异步的客户端 TCP Socket 连接。
- NioServerSocketChannel,异步的服务器端 TCP Socket 连接。
- NioDatagramChannel,异步的 UDP 连接。
- NioSctpChannel,异步的客户端 Sctp 连接。
- NioSctpServerChannel,异步的 Sctp 服务器端连接,这些通道涵盖了 UDP 和 TCP 网络 IO 以及文件 IO。
ChannelHandler
ChannelHandler 是一个接口,处理 I/O 事件或拦截 I/O 操作,并将其转发到其 ChannelPipeline(业务处理链)中的下一个处理程序。
ChannelInboundHandler 用于处理入站 I/O 事件。
ChannelOutboundHandler 用于处理出站 I/O 操作。
或者
ChannelInboundHandlerAdapter 用于处理入站 I/O 事件。
ChannelOutboundHandlerAdapter 用于处理出站 I/O 操作。
ChannelDuplexHandler 用于处理入站和出站事件。ChannelHandlerContext
保存 Channel 相关的所有上下文信息,同时关联一个 ChannelHandler 对象。ChannelPipline
保存 ChannelHandler 的 List,用于处理或拦截 Channel 的入站事件和出站操作。
ChannelPipeline 实现了一种高级形式的拦截过滤器模式,使用户可以完全控制事件的处理方式,以及 Channel 中各个的 ChannelHandler 如何相互交互。
在 Netty 中每个 Channel 都有且仅有一个 ChannelPipeline(一个包含多个channelHandler的list) 与之对应,
一个 Channel 包含了一个 ChannelPipeline,而 ChannelPipeline 中又维护了一个由 ChannelHandlerContext 组成的双向链表,并且每个 ChannelHandlerContext 中又关联着一个 ChannelHandler。channelFuture
在 Netty 中所有的 IO 操作都是异步的,不能立刻得知消息是否被正确处理。
但是可以过一会等它执行完成或者直接注册一个监听,具体的实现就是通过 Future 和 ChannelFutures,他们可以注册一个监听,当操作执行成功或失败时监听会自动触发注册的监听事件。
Netty架构—代码启动分析
初始化并启动 Netty 服务端过程如下:
public static void main(String[] args) { // 创建mainReactor NioEventLoopGroup boosGroup = new NioEventLoopGroup(); // 创建工作线程组 NioEventLoopGroup workerGroup = new NioEventLoopGroup(); final ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap // 组装NioEventLoopGroup .group(boosGroup, workerGroup) // 设置channel类型为NIO类型 .channel(NioServerSocketChannel.class) // 设置连接配置参数 .option(ChannelOption.SO_BACKLOG, 1024) .childOption(ChannelOption.SO_KEEPALIVE, true) .childOption(ChannelOption.TCP_NODELAY, true) // 配置入站、出站事件handler .childHandler(new ChannelInitializer<NioSocketChannel>() { @Override protected void initChannel(NioSocketChannel ch) { // 配置入站、出站事件channel ch.pipeline().addLast(...); ch.pipeline().addLast(...); } }); // 绑定端口 int port = 8080; serverBootstrap.bind(port).addListener(future -> { if (future.isSuccess()) { System.out.println(new Date() + ": 端口[" + port + "]绑定成功!"); } else { System.err.println("端口[" + port + "]绑定失败!"); } });
- 步骤:
- 初始化创建 2 个 NioEventLoopGroup,其中 boosGroup 用于 Accetpt 连接建立事件并分发请求,workerGroup 用于处理 I/O 读写事件和业务逻辑。
- 基于 ServerBootstrap(服务端启动引导类),配置 EventLoopGroup、Channel 类型,连接参数、配置入站、出站事件 handler。
绑定端口,开始工作。 - 分析NioEventLoopGroup。
NioEventLoopGroup 相当于 1 个事件循环组,这个组里包含多个事件循环 NioEventLoop,每个 NioEventLoop 包含 1 个 Selector 和 1 个事件循环线程。
- 执行请求过程:
- 绑定端口过程:
Netty架构—主从Reacor多线程执行过程
每个 MainReactor NioEventLoop 循环执行的任务包含 3 步
1.轮询accept
2.建立连接,生成NioSocketChannel,并注册到SubReactor的selector上
3.处理任务中的队列,runAllTasks每个SubReactor NioEventLoop 循环执行的任务包含 3 步:
1.轮询read,write事件,
2.处理I/O事件,在NioSocketchannel可读可写时处理read write,
3.处理任务队列中的任务任务队列中的任务有三种典型使用场景
1.用户自定义的普通任务
2.用户自定义的定时任务
3.非当前Reactor线程调用channel的各种方法
Netty架构学习问题
- Netty中采用了哪些设计模式?
- 为什么我们在学习Netty的过程中主要是针对我们的服务器端开发而不是我们的客户端开发?
Netty—网络的高层建筑相关推荐
- Netty网络编程聊天项目
Netty网络编程聊天项目 后端编写 导入依赖 <dependencies><dependency>&l ...
- Netty网络编程实战2,使用Netty开发聊天室功能
目录 一.服务端 1.主程序类 2.自定义初始化器 3.自定义处理器 二.客户端 1.主程序类 2.自定义初始化器 3.自定义处理器 三.启动服务端.客户端 1.服务端:你好,我是服务端,哪吒编程 2 ...
- Netty网络框架学习笔记-16(心跳(heartbeat)服务源码分析)
Netty网络框架学习笔记-16(心跳(heartbeat)服务源码分析_2020.06.25) 前言: Netty 作为一个网络框架,提供了诸多功能,比如编码解码等,Netty 还提供了非常重要的一 ...
- 基于 Netty 网络编程项目实战课程
一 基于 Netty 网络编程项目实战课程 1项目介绍 2Netty 介绍与相关基础知识 2.1Netty 介绍 简介 Netty 是由 JBOSS 提供的一个 java 开源框架.Netty 提供异 ...
- Netty网络编程第三卷
Netty网络编程第三卷 三. Netty 进阶 1. 粘包与半包 1.1 粘包现象 1.2 半包现象 1.3 现象分析 MSS 限制 Nagle 算法 1.4 解决方案 方法1,短链接 方法2,固定 ...
- Springboot+netty网络聊天
Springboot+netty网络聊天 一.新建SringWeb项目 二.环境配置 三.代码实现 (一)项目结构 (二)代码 (三)测试文件 四.运行结果 五.总结 六.参考资料 一.新建Sring ...
- Netty网络编程第八卷
Netty网络编程第八卷 整体架构 ByteBuf Channel EventLoop和EventLoopGroup ChannelFuture ChannelHandler和ChannelPipel ...
- netty支持哪些协议_从零学习netty网络IO通讯开发框架
Netty 是一个利用 Java 的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的 API 的客户端/服务器框架.是一款基于NIO(Nonblocking I/O,非阻塞IO)开发的网络通信框 ...
- Netty网络编程(三):Channel详解
文章目录 简介 Channel详解 异步IO和ChannelFuture Channel的层级结构 释放资源 事件处理 总结 简介 Channel是连接ByteBuf和Event的桥梁,netty中的 ...
最新文章
- CSS内容溢出时,显示省略号
- centos7安装Filebeat采集日志文件存到Elasticsearch
- 11选5下期算法_玫瑰2020196期福彩3D推荐:双胆2、6,和值看好11
- mysql 交叉表行转列_Oracle行转列、列转行的Sql语句总结
- 最长公共子序列(POJ1458)
- Mac实用技巧:怎样使用终端在macOS Big Sur Finder中锁定文件!
- redis服务器环境下mysql实现lnmp架构缓存
- 网站抓取精灵V3.0正式版
- java易宝支付接口文档_易宝支付的最新接口文档
- 深入理解设计模式之模板模式
- android局域网连接TSC桌面打印机打印
- 哈哈,电驴资源 的下载问题
- 大疆精灵4rtk照片信息读取
- oracle to_date 函数
- 将古典融汇到现代(一) ---皮尔斯逻辑之四
- 随笔3:有调节的中介示例之 Model 1
- 一个nginx使用同一端口不同域名代理到不同网站
- 1173 Problem V 《C语言程序设计》江宝钏主编-习题6-2-排列数
- PHP 微信JSP支付
- 软件测试多次点击按钮叫什么方法,常见控件的测试点 - 爱昵容儿 的个人空间 - 51Testing软件测试网 51Testing软件测试网-软件测试人的精神家园...
热门文章
- 对第三方支付课税问题的分析[2011年]
- ppt2007 无法翻页
- Linux_Linux查看某个进程下面的线程
- net6中webapi配置
- html编辑ko,BootstrapTable+KnockoutJS相结合实现增删改查解决方案(三)两个Viewmodel搞定增删改查...
- rust矿洞绳子怎么爬下_腐蚀RUST实用技巧分享 教你在游戏中横着走
- 汇编(一):基础知识
- TrinityCore 魔兽世界私服11159 完整配置
- 来电街电小电怪兽,这三电一兽如何把充电宝练成了吞金兽?
- C# 实现真正的透明控件(Windows桌面程序)