Netty中的Reactor模型实现
Netty版本:4.1.17
Reactor模型是Doug Lea在《Scalable IO in Java》提出的,主要是针对NIO的。
其中的主从Reactor模式在Netty中的配置如下:
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workerGroup);
基于此,我们来看下Netty是如何实现主从Reactor模式的。
EventLoop
EventLoop
就是Netty中的Reactor
,可以说它就是Netty的引擎,负责Channel上IO就绪事件的监听
,IO就绪事件的处理
,异步任务的执行
驱动着整个Netty的运转。
Netty支持不同IO模型
下,EventLoop
有着不同的实现,我们只需要切换不同的实现类就可以完成对NettyIO模型
的切换。
BIO | NIO | AIO |
---|---|---|
ThreadPerChannelEventLoop | NioEventLoop | AioEventLoop |
EventLoopGroup
Netty中的Reactor
是以Group
的形式出现的,EventLoopGroup
正是Reactor组
的接口定义,负责管理Reactor
,Netty中的Channel
就是通过EventLoopGroup
注册到具体的Reactor
上的。
Netty的IO线程模型是主从Reactor多线程模型
,主从Reactor线程组
在Netty源码中对应的其实就是两个EventLoopGroup
实例。
不同的IO模型
也有对应的实现:
BIO | NIO | AIO |
---|---|---|
ThreadPerChannelEventLoopGroup | NioEventLoopGroup | AioEventLoopGroup |
多种NIO的实现
Common | Linux | Mac |
---|---|---|
NioEventLoopGroup | EpollEventLoopGroup | KQueueEventLoopGroup |
NioEventLoop | EpollEventLoop | KQueueEventLoop |
NioServerSocketChannel | EpollServerSocketChannel | KQueueServerSocketChannel |
NioSocketChannel | EpollSocketChannel | KQueueSocketChannel |
我们通常在使用NIO模型
的时候会使用Common列
下的这些IO模型
核心类,Common类
也会根据操作系统的不同自动选择JDK
在对应平台下的IO多路复用技术
的实现。
而Netty自身也根据操作系统的不同提供了自己对IO多路复用技术
的实现,比JDK
的实现性能更优。比如:
-
JDK
的 NIO默认
实现是水平触发
,Netty 是边缘触发(默认)
和水平触发可切换。 -
Netty 实现的垃圾回收更少、性能更好。
我们编写Netty服务端程序的时候也可以根据操作系统的不同,采用Netty自身的实现来进一步优化程序。做法也很简单,直接将上图中红框里的实现类替换成Netty的自身实现类即可完成切换。
由此,可以看到,我们使用Common下的NIO实现时,在Linux环境下,会自动使用水平触发的epoll。
PS: 在NIO模型
下Netty会自动
根据操作系统以及版本的不同选择对应的IO多路复用技术实现
。比如Linux 2.6版本以上用的是Epoll
,2.6版本以下用的是Poll
,Mac下采用的是Kqueue
。
水平触发和边缘触发看附录二。
附录一:Netty如何根据操作系统选择JDK对应Selector
的实现
Netty中,是通过SelectorProvider
来根据操作系统的不同选择JDK在不同操作系统版本下的对应Selector
的实现。Linux下会选择Epoll
,Mac下会选择Kqueue
。
SelectorProvider
是在前面介绍的NioEventLoopGroup类
构造函数中通过调用SelectorProvider.provider()
被加载,并通过NioEventLoopGroup#newChild
方法中的可变长参数Object... args
传递到NioEventLoop
中的private final SelectorProvider provider
字段中。
SelectorProvider的加载过程:
private static class Holder {static final SelectorProvider INSTANCE = provider();@SuppressWarnings("removal")static SelectorProvider provider() {PrivilegedAction<SelectorProvider> pa = () -> {SelectorProvider sp;if ((sp = loadProviderFromProperty()) != null)return sp;if ((sp = loadProviderAsService()) != null)return sp;return sun.nio.ch.DefaultSelectorProvider.get();};return AccessController.doPrivileged(pa);}...
从SelectorProvider
加载源码中我们可以看出,SelectorProvider
的加载方式有三种,优先级如下:
-
通过系统变量
-D java.nio.channels.spi.SelectorProvider
指定SelectorProvider
的自定义实现类全限定名
。通过应用程序类加载器(Application Classloader)
加载。 -
通过
SPI
方式加载。在工程目录META-INF/services
下定义名为java.nio.channels.spi.SelectorProvider
的SPI文件
,文件中第一个定义的SelectorProvider
实现类全限定名就会被加载 -
如果以上两种方式均未被定义,那么就采用
SelectorProvider
系统默认实现sun.nio.ch.DefaultSelectorProvider
。不同操作系统中JDK对于DefaultSelectorProvider
会有所不同,可以看到,当我们在Mac下打开DefaultSelectorProvider的源码时,可以发现
DefaultSelectorProvider自动适配了KQueue
实现,为:KQueueSelectorProvider。在Windows下,DefaultSelectorProvider自动适配了Epoll
实现,为WEPollSelectorProvider
附录二:再谈水平触发和边缘触发
网上有大量的关于这两种模式的讲解,大部分讲的比较模糊,感觉只是强行从概念上进行描述,看完让人难以理解。所以在这里,笔者想结合上边epoll
的工作过程,再次对这两种模式做下自己的解读,力求清晰的解释出这两种工作模式的异同。
经过上边对epoll
工作过程的详细解读,我们知道,当我们监听的socket
上有数据到来时,软中断会执行epoll
的回调函数ep_poll_callback
,在回调函数中会将epoll
中描述socket信息
的数据结构epitem
插入到epoll
中的就绪队列rdllist
中。随后用户进程从epoll
的等待队列中被唤醒,epoll_wait
将IO就绪
的socket
返回给用户进程,随即epoll_wait
会清空rdllist
。
水平触发和边缘触发最关键的区别就在于当socket
中的接收缓冲区还有数据可读时。epoll_wait
是否会清空rdllist
。
-
水平触发:在这种模式下,用户线程调用
epoll_wait
获取到IO就绪
的socket后,对Socket
进行系统IO调用读取数据,假设socket
中的数据只读了一部分没有全部读完,这时再次调用epoll_wait
,epoll_wait
会检查这些Socket
中的接收缓冲区是否还有数据可读,如果还有数据可读,就将socket
重新放回rdllist
。所以当socket
上的IO没有被处理完时,再次调用epoll_wait
依然可以获得这些socket
,用户进程可以接着处理socket
上的IO事件。 -
边缘触发: 在这种模式下,
epoll_wait
就会直接清空rdllist
,不管socket
上是否还有数据可读。所以在边缘触发模式下,当你没有来得及处理socket
接收缓冲区的剩下可读数据时,再次调用epoll_wait
,因为这时rdlist
已经被清空了,socket
不会再次从epoll_wait
中返回,所以用户进程就不会再次获得这个socket
了,也就无法在对它进行IO处理了。除非,这个socket
上有新的IO数据到达,根据epoll
的工作过程,该socket
会被再次放入rdllist
中。
如果你在
边缘触发模式
下,处理了部分socket
上的数据,那么想要处理剩下部分的数据,就只能等到这个socket
上再次有网络数据到达。
在Netty
中实现的EpollSocketChannel
默认的就是边缘触发
模式。JDK
的NIO
默认是水平触发
模式。
参考:聊聊Netty那些事儿之Reactor在Netty中的实现(创建篇)
聊聊Netty那些事儿之从内核角度看IO模型
相关文章:
Netty中的Reactor模型实现
Netty版本:4.1.17 Reactor模型是Doug Lea在《Scalable IO in Java》提出的,主要是针对NIO的。 其中的主从Reactor模式在Netty中的配置如下: EventLoopGroup bossGroup new NioEventLoopGroup(1); EventLoopGroup workerGroup new NioEv…...
dll丢失应该怎么解决,总结5种解决DLL丢失问题的方法
在数字时代,我们与计算机的每一天都密不可分。然而,就像所有技术产品一样,我们的计算设备也时不时地会出现一些问题,让人头疼不已。就在上周,我遭遇了一个令人崩溃的技术挑战——DLL文件丢失。这个看似微不足道的小问题…...
dial tcp 10.96.0.1:443: connect: no route to host
1、创建Pod一直不成功,执行kubectl describe pod runtime-java-c8b465b98-47m82 查看报错 Warning FailedCreatePodSandBox 2m17s kubelet Failed to create pod sandbox: rpc error: code Unknown desc failed to setup network for…...
VScode创建ROS项目 ROS集成开发环境
ROS使用VScode创建项目步骤 1.创建ROS工作空间2.启动VScode3.VScode编译ROS4.创建ROS功能包C语言开发Python语言开发 本文章介绍了如何在Ubuntu18.04系统下搭建VScode 的ROS项目 搭建项目分为一下几个步骤: 1.创建ROS工作空间 创建一个demo的ROS工作空间࿰…...
nodejs从基础到实战学习笔记-nodejs简介
一、Node.js简介 • Node.js是一个能够在服务器端运行JavaScript的开放源代码、跨平台JavaScript运行环境。 • Node采用Google开发的V8引擎运行js代码,使用事件驱动、非阻塞和异步I/O模型等技术来提高性能,可优化应用程序的传输量和规模。 1.1 特性 …...
2024年最新版------二进制安装部署Kubernetes(K8S)集群
Kubernetes二进制集群部署 文章目录 Kubernetes二进制集群部署资源列表基础环境一、环境准备1.1、绑定映射关系1.2、所有主机安装Docker1.3、所有主机设置iptables防火墙 二、生成通信加密证书2.1、master上成功CA证书2.2.1、创建证书存放位置并安装证书生成工具2.2.2、拷贝证书…...
【mysql】关键词搜索实现
关键词搜索实现两种方式 -- 方式1 模糊匹配搜索 -- 场景一:搜索出来地址内包含‘李’和‘中国’的 select * from tn_md_cust_link where address like concat (%李%) or address like concat (%中国%) -- 场景二:搜索地址或者名称包含 ‘181’ 的 …...
Python面试十问2
一、如何使用列表创建⼀个DataFrame # 导入pandas库 import pandas as pd# 创建一个列表,其中包含数据 data [[A, 1], [B, 2], [C, 3]]# 使用pandas的DataFrame()函数将列表转换为DataFrame df pd.DataFrame(data, columns[Letter, Number]) # 列名# 显示创建的…...
C# OpenCvSharp 图像处理函数-颜色通道-cvtColor
使用 OpenCvSharp 中的 cvtColor 函数进行图像颜色转换 在图像处理领域,颜色空间转换是一个非常常见的操作。OpenCvSharp 提供了一个强大的函数 cvtColor 来处理这类转换。本文将详细介绍 cvtColor 函数的使用方法,并通过具体的示例演示如何在实际项目中应用这些知识。 函数…...
总结之LangChain(三)——模型IO缓存
一、聊天模型缓存 LangChain为聊天模型提供了一个可选的缓存层。这有两个好处: 如果您经常多次请求相同的完成结果,它可以通过减少您对LLM提供程序的API调用次数来帮您节省费用。 它可以通过减少您对LLM提供程序的API调用次数来加快您的应用程序速度。…...
判断一个Java服务是不是GateWay
方法 直接在对应服务的url后变加上后缀/actuator/gateway/routes,看是否会返回Gateway的路由信息。 如果返回了GateWay的路由列表,则该服务为Gateway服务。...
三次插值曲线--插值技术
三次插值曲线 1.1.三次样条曲线 三次样条曲线的基本思想是,在给定的一系列点(称为控制点或数据点)之间,通过一系列三次多项式曲线段来拟合这些点,使得整个曲线既平滑又准确地通过所有控制点。 1.1.1.数学定义 给定…...
python循环结构
1.while 循环 语句: while 循环条件表达式: 代码块 else: 代码块 小练: 设计一百以内的偶数相加 n 0 while n < 100:n 1if n % 2 0 :print(n) 判断是不是闰年(四年一润和百年不润,或者四百年一润&am…...
深入理解Netty的Pipeline机制:原理与实践详解
深入理解Netty的Pipeline机制:原理与实践详解 Netty是一个基于Java的高性能异步事件驱动的网络应用框架,广泛应用于高并发网络编程。(学习netty请参考:深入浅出Netty:高性能网络应用框架的原理与实践)Nett…...
直方图均衡化示例
禹晶、肖创柏、廖庆敏《数字图像处理(面向新工科的电工电子信息基础课程系列教材)》 图3-17...
私域电商新纪元:消费增值模式的创新与成功实践
大家好,我是吴军,很高兴能够与您分享私域电商领域的魅力与机遇。今天,我将为大家呈现一个令人瞩目的成功案例,这个案例充分展现了私域电商的巨大潜力和无限可能。 在短短一个月的时间里,我们的客户成功实现了业绩的飞跃…...
Java——IO流(一)-(6/8):字节流-FileInputStream 每次读取多个字节(示例演示)、一次读取完全部字节(方式一、方式二,注意事项)
目录 文件字节输入流:每次读取多个字节 实例演示 注意事项 文件字节输入流:一次读取完全部字节 方式一 方式二 注意事项 文件字节输入流:每次读取多个字节 用到之前介绍过的常用方法: 实例演示 需求:用每次读取…...
服务器SSH 免密码登录
1. 背景 为了服务器的安全着想,设置的服务器密钥非常长。但是这导致每次连接服务器都需要输入一长串的密码,把人折腾的很痛苦,所以我就在想,能不能在终端SSH的时候无需输入密码。 windows 可以使用 xshell 软件,会自…...
Linux安装MySQL以及远程连接
1、Linux安装MySQL 1.1、准备解压包 MySQL5.x解压包 提取码:9y7n 1.2、通过rpm脚本安装 切记安装顺序:common --> libs --> client --> server 因为它们之间存在依赖关系,所以务必按照顺序安装 安装前请确保当前目录/文…...
SQL Server 数据库分页技术详解:选择最佳方法优化查询性能”。
当今数据驱动的应用程序中,数据库分页技术在优化查询性能和提升用户体验中扮演着重要角色。在 SQL Server 环境下,开发者面对大数据集时,常常需要选择合适的分页方法以平衡功能需求和性能优化。本文将详细介绍 SQL Server 中几种主要的分页技…...
electron录制-镜头缩放、移动
要求 1、当录屏过程中,鼠标点击,镜头应该往点击处拉近,等一段时间还原 2、录屏过程中,可能会发生多次点击,但是点击位置偏差大,可能会导致缩放之后,画面没出来,因此需要移动镜头帧 …...
红队内网攻防渗透:内网渗透之内网对抗:信息收集篇自动项目本机导出外部打点域内通讯PillagerBloodHound
红队内网攻防渗透 1. 内网自动化信息收集1.1 本机凭据收集类1.1.1、HackBrowserData 快速获取浏览器的账户密码1.1.2、Searchall 快速搜索服务器中的有关敏感信息还有浏览器的账户密码1.1.3、Pillager 适用于后渗透期间的信息收集工具,可以收集目标机器上敏感信息1.2 对外打点…...
2024最新IDEA插件开发+发布全流程 SelectCamelWords[选中驼峰单词](idea源代码)
2024最新IDEA插件开发(发布)-SelectCamelWords[选中驼峰单词](idea源代码) 参考文档 Jetbrains Idea插件开发文档: https://plugins.jetbrains.com/docs/intellij/welcome.html代码地址:https://github.com/yangfeng…...
【网络安全】网络安全基础精讲 - 网络安全入门第一篇
目录 一、网络安全基础 1.1网络安全定义 1.2网络系统安全 1.3网络信息安全 1.4网络安全的威胁 1.5网络安全的特征 二、入侵方式 2.1黑客 2.1.1黑客入侵方式 2.1.2系统的威胁 2.2 IP欺骗 2.2.1 TCP等IP欺骗 2.2.2 IP欺骗可行的原因 2.3 Sniffer探测 2.4端口扫描技术…...
初识 GPT-4 和 ChatGPT
文章目录 LLM 概述理解 Transformer 架构及其在 LLM 中的作用解密 GPT 模型的标记化和预测步骤 想象这样⼀个世界:在这个世界里,你可以像和朋友聊天⼀样快速地与计算机交互。那会是怎样的体验?你可以创造出什么样的应用程序?这正是…...
【C语言】解决C语言报错:Array Index Out of Bounds
文章目录 简介什么是Array Index Out of BoundsArray Index Out of Bounds的常见原因如何检测和调试Array Index Out of Bounds解决Array Index Out of Bounds的最佳实践详细实例解析示例1:访问负索引示例2:访问超出上限的索引示例3:循环边界…...
【C++】一个极简但完整的C++程序
一、一个极简但完整的C程序 我们编写程序是为了解决问题和任务的。 1、任务: 某个书店将每本售出的图书的书名和出版社,输入到一个文件中,这些信息以书售出的时间顺序输入,每两周店主会手工计算每本书的销售量、以及每个出版社的…...
Lua迭代器详解(附加红点功能实例)
Lua迭代器详解与用法 1. 什么是迭代器2. 为什么需要理解迭代器的原理3. 迭代器的实现0. 闭包1. 有状态迭代器2. 无状态迭代器 4. 红点树系统基础 1. 什么是迭代器 迭代器是一种能让我们遍历一个集合中的所有元素的代码结构。比如常用ipairs()和pairs()。 2. 为什么需要理解迭代…...
锂磷硫(LPS)属于硫化物固态电解质 Li7P3S11是代表性产品
锂磷硫(LPS)属于硫化物固态电解质 Li7P3S11是代表性产品 锂磷硫(LPS),为非晶态材料,是硫化物固态电解质代表性产品之一,具有热稳定性好、成本较低等优点,在固态电解质中离子电导率较…...
PointCloudLib 点云边缘点提取 C++版本
0.实现效果 1.算法原理 PCL(Point Cloud Library)中获取点云边界的算法主要基于点云数据的几何特征和法向量信息。以下是对该算法的详细解释,按照清晰的格式进行归纳: 算法概述 PCL中的点云边界提取算法主要用于从3D点云数据中识别并提取出位于物体边界上的点。这些边界…...
哈尔滨最新/关键词优化如何
new Date(str)MM-dd-yyyy yyyy/MM/dd MM/dd/yyyy MMMM dd, yyyy MMM dd, yyyy dd MMM yyyydd MMMM yyyyMMM dd yyyyMMMM dd yyyy转载于:https://www.cnblogs.com/qinghao/archive/2010/01/18/1651145.html...
山东省招投标信息网/扬州seo优化
动态菜单: 不同用户登录后,应该看到不同菜单结构 1、 修改 index.html 加载基本菜单 url 路径 2、 在 MenuAction 添加 showMenu 方法 3、 编写业务层 调用 DAO ”from Menu m inner join fetch m.roles r inner join fetch r.users u where…...
建设企业网站的公司/seo sem是什么
使用 Power BI Desktop 从数据获得见解,然后进行相关操作利用可视化分析免费创建内容丰富的交互式报表,一切尽在指尖。日前,Power BI Desktop迎来2019年又一次重大更新!Power BI Desktop 2019年4月版重大更新Power BI Desktop 201…...
电子商务网站的类型/app拉新
前言 为防止背题,大部分题目不设标准答案,重点考察面试者的基础知识和思维逻辑,答案的提示见后面。 正文 题目1、举例两个遇到过印象深刻的外网Crash,并介绍如何发现、定位、解决; 题目2、举例两个性能问题的优化&…...
企业网站目的/手机注册网站
概念及注意事项1、组函数:对一组数据进行操作,最后返回一个值,用作统计分析,求所有的非空值。2、关键字DISTINCT可以排除重复值。3、参数的类型可以是CHAR,VARCHAR2,NUMBER,DATE4、除了COUNT(*)外,其他所有组函数都忽略空值&#…...
在哪个国家做垂直网站好/营业推广的方式
按键精灵将表格录入网页.doc按键精灵将表格录入网页篇一:基于按键精灵的自动输入程序的实现2012.3.1基于按键精灵的自动输入程序的实现高琪琪(无锡职业技术学院 江苏 无锡 214121)摘要:本文讨论如何通过按键精灵读取excel表格中的内容,之后通…...