Netty源码解读-EventLoop(二)
一、简介
NioEventLoop的重要组成:Selector、线程、任务队列,他既会处理io事件,也会处理普通任务和定时任务.
1.下面是Selector,注意有两个哦后面会讲
2.下面的爷爷类提供的Thread变量,其实下面发excutor用的就是这个一个线程。
任务队列就是thread上面的这个taskQueue变量

3.从曾祖父类中可以看到处理定时任务的任务队列

二、带着问题读源码
2.1selector在何时创建?
答案:在构造方法的openSelector()方法中被创建


2.2EventLoop为啥有两个Selector对象?
答案:为了在遍历SelectedKey时提升性能
继续往下看看openSelector方法:

SelectedSelectionKeySet的部分源码展现:

再看EventLoop构造方法就懂了:
1.selectorTuple 就是 new SelectorTuple(unwrappedSelector,new SelectedSelectionKeySetSelector(unwrappedSelector, selectedKeySet))
2.selectorTuple.selector就是new SelectedSelectionKeySetSelector(unwrappedSelector, selectedKeySet))

3.new SelectedSelectionKeySetSelector(unwrappedSelector, selectedKeySet))的底层可以看到,基本就是对unwrappedSelector进行了包装

2.3.EventLoop的Nio线程何时被启动?
答案:当首次调用execute方法时,通过state状态位控制线程只会启动一次
1.可以写一个测试代码,咱们追execute方法就行!

下面是其源码展示:

2.在inEventLoop的底层是通过thread变量和当前线程是否相等来判断是不是Nio线程
第一次执行时thread等于null,当然会返回false

3.随后通过addTask方法将任务提交到任务队列


4.第一次执行由于不属于nio线程,会执行startThread


2.4提交普通任务会不会结束select阻塞?
答案:会
1.重点追一下上面提及的run方法

发现netty的select底层是用了带超时时间的select方法

2.回到execute方法,分析后面的普通任务进来的执行逻辑
第二次execute方法进来,肯定是走下面这个wakeUp的逻辑

从底层可以看出wakeUp可以释放selector的select等待

2.5wakeup方法中的代码怎么理解? & wakenUp变量的作用是什么?
答案:只有其他线程提交任务时,才会调用上面2.4提到的selector.wakeup
wakenUp的作用:如果有多个其他线程都来提交任务,使用cas算法避免wakeUp被频繁调用
2.6每次循环时,什么时候会进入SelectStrategy.SELECT分支
答案:当没有任务时,才会进入SelectStrategy.SELECT分支,当有任务时,会调用selectNow方法,顺便拿到io事件
这得分析switch括号中方法的返回结果了,因为具体走哪个分支完全有这个case决定

由底层源码可知,档hasTasks()返回为fasle时,也就是没有任务才会走SELECT分支

如果有任务,则马上调用selector.selectNow把事件给拿到

2.7何时会select阻塞,阻塞多久?
答案:没有任务时阻塞一秒左右,只有三种情况才会跳出for的死循环:1.超时时间到了2.有任务3.有事件


2.8Nio空轮询bug在哪体现?如何解决?
答案:
1.bug的体现就是selector.select(timeout)方法可能没阻塞住,导致for循环一直空转(linux平台会产生)
2.解决办法是增加了selectCnt计数器,每次循环都会加1,默认达到512次就会认为bug产生,换一个新的selector,并会自动break

下面是for循环空转的终止条件,达到512次会重新创建一个新的selector,替换掉有问题的selector

2.9 ioRatio控制什么?设置为100有何作用?
答案:ioRatio控制处理io事件所占用的时间比例,如果设置100会让普通任务全部执行完(强烈不推荐!)。咱们可以看else的逻辑
由于Netty线程是单线程,如果处理普通任务的时间过长,势必会影响到io事件的处理
ioTime代表执行io事件处理耗费的时间

2.10selectedKeys优化是怎么回事?
答案:就是用数组类型的selectedKeys代替原来Set结构的SelectedKey,提升访问的效率
在上面2.2中提到了,selectedKeys是优化后数组类型的key集合,所以默认优化后会走if中的分支

继续追processSelectKeysOptimized方法,发现逻辑大致就是拿到nioChannel这个附件,执行其pipline中绑定的handler

processSelectedKey方法的底层是根据事件的类型做不同的处理

三、Netty中的Accept流程
原生nio中accept流程主要干了下面六件事情:
上面2.6-2.10已经分析到了前面三件事情,本段落时分析后续的三件事情在哪执行!

1.继续分析2.10中提到的unsafe.read(),这里会调到NioMessageUnsafe类中,我们关注doReadMessage这个方法即可

从doReadMessages方法中可以看到nio原生的accept的过程,并主动创建了一个NioSocketChannel。而设置为非阻塞的过程在new NioSocketChannel方法中,有兴趣的朋友可以追一下

2.回到unsafe.read方法,往下继续看
这个pipeline.fireChannelRead就会调用到Netty源码解读-server端中2.3.3提到的acceptHandler

也就是会调用到ServerBootstrapAcceptor.channelRead,主要是设置一些参数,然后执行regitster方法

childGroup.register这个方法和Netty源码解读-server端中2.3.1的register的过程基本一致,也会切换成nio线程执行register0方法


继续分析pipeline.fireChannelActive,他势必也会执行head节点的active方法,又是熟悉的配方

又是在AbstractNioChannel.doBeginRead方法中关注到read事件

3.read事件触发
虽然该事件也会走2.10中提到的unsafe.read(),但和accept事件不同,他会进入NioByteUnsafe子类
会在doReadBytes方法中读取client端发送过来的数据,可以打断点看到经过这一行,byteBuf读指针发生了变化

后续的逻辑是通知其他的hander,链式执行…

相关文章:
Netty源码解读-EventLoop(二)
一、简介 NioEventLoop的重要组成:Selector、线程、任务队列,他既会处理io事件,也会处理普通任务和定时任务. 1.下面是Selector,注意有两个哦后面会讲 2.下面的爷爷类提供的Thread变量,其实下面发excutor用的就是这个…...
OSI模型详解
今天,我们详解OSI(Open System Inter-connection Reference Model)模型,来看看工业物联网的网络互联和数据互通。 OSI模型 1984年,国际标准化组织(International Organization for Standardization&#…...
Share Creators完成500万美元融资,以工具化手段帮助企业从数字资产管理中解放
近日,总部位于旧金山湾区的初创公司Share Creators宣布完成了新一轮500万美元的融资,投资方为五源资本和福昕PDF。本轮融资主要用于扩大客户基础,并加速在美国、欧洲和亚洲的业务发展。近几年,企业内容及数字资产管理全球市场正在…...
几个Base64编码工具,也有蹊跷
起因 需求:对一段内容进行base64加密,然后通过url的get请求进行发送到后台,由于加密的内容比较少,base64串也不是很长,我认为此方案可行。 于是找了三个base64编码的在线工具,分别是: 平台1&…...
Python|每日一练|排序|递归|字符串|数组|动态规划|单选记录:以特殊格式处理连续增加的数字|正则表达式匹配|地下城游戏
1、以特殊格式处理连续增加的数字(排序) 贡献者:EricLao 给出一串数字, 程序要把数字按照这样的格式输出,把连续增加的数字用 [x-y] 的形式表示,只显示这一组顺序数字的首位两个数字,不连续增…...
Spring Cloud微服务网关Gateway组件
目录 网关简介 什么是Spring Cloud Gateway Spring Cloud Gateway 功能特征 核心概念 工作原理 Spring Cloud Gateway快速开始 环境搭建 集成Nacos 路由断言工厂(Route Predicate Factories)配置 自定义路由断言工厂 过滤器工厂( …...
cluster nodes(集群节点)
CLUSTER NODES 复制 自3.0.0起可用。 时间复杂度: O(N)其中N是 Cluster 节点的总数 Redis 集群中的每个节点都有其当前集群配置的视图,由已知节点的集合给出,我们与这些节点的连接状态,它们的标志&…...
【Android学习】下载jar慢和gradle慢的情况
目录 问题出现的原因 解决方法 解决Gradle下载问题:手动安装 解决jar包下载慢问题:更改下载源 问题出现的原因 国内访问谷歌被墙导致访问速度慢或者干脆无法下载 解决方法 解决Gradle下载问题:手动安装 访问官网Gradle | Release Candi…...
下一个排列-力扣31-java
一、题目描述整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。例如,arr [1,2,3] ,以下这些都可以视作 arr 的排列:[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。更正式地&…...
前端面试题
1.HTTP request报文结构是怎样的 1.首行是Request-Line包括:请求方法,请求URI,协议版本,CRLF(换行符) 2.首行之后是若干行请求头,包括general-header,request-header或者entity-hea…...
jsp游戏门户网站系统Myeclipse开发mysql数据库web结构java编程计算机网页项目
一、源码特点 jsp 游戏门户网站系统 是一套完善的web设计系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发,数据库为Mysql,使…...
Git与IDEA强强联合(HTTPS协议连接)
最近在写项目的时候,在台式机和笔记本之间频繁切换,竟然还是用qq传压缩包,我自己都感觉无语,有git这样强大的版本管理工具,我竟然没想起来。然后也没有相关的博文就想来更新一篇。 那么如何使idea和git强强联合呢&…...
leetcode 第二题:两数相加-C语言实现
题目地址 备注: 不要忘记最后一个进位的可能。可以使用typedef,来简化struct的书写 代码实现: #include<stdio.h> #include<stdlib.h>struct listNode {int val;struct listNode* next; };// 使用typedef typedef struct lis…...
【人工智能】PTP网络时钟服务器在智能驾驶里的重要性
【人工智能】PTP网络时钟服务器在智能驾驶里的重要性 【人工智能】PTP网络时钟服务器在智能驾驶里的重要性 一辆宣称具备L4/L5自动驾驶功能的车辆,如果多个激光雷达之间的时间同步不够精确?如果传感器感知数据通过以太网传输到智驾域控制器的延迟不可控…...
【蓝桥杯集训3】二分专题(3 / 5)
目录 二分模板 1460. 我在哪? - 二分答案 哈希表 1221. 四平方和 - 哈希表 / 二分 1、哈希表 2、二分 自定义排序 1227. 分巧克力 - 113. 特殊排序 - 二分模板 l r >> 1 —— 先 r mid 后 l mid1 —— 寻找左边界 —— 找大于某个数的最小值lr…...
在成都的哪个培训机构学习Java好呢?
自从小课06年进入成都这个IT培训市场以来,短短十几年,招过很多学员,也见证过很多机构的起起落落。心中有万分的感慨,总结下来有这几点分享给大家,在选择培训机构时能看清本质,找到适合自己靠谱的机构学Java…...
传输层重要协议之UDP协议和TCP协议详解
更多关于UDP协议和TCP协议请移步官网:https://www.rfc-editor.org/standards#ISUDP标准协议文档-RFC 768TCP标准协议文档-RFC 793UDP协议详解UDP协议的特点:无连接、不可靠传输、面向数据报和全双工。UDP协议报文结构:关于端口号:…...
BNB Greenfield 成存储赛道“新贵”,BNB 生态的野心与破局
“从BNB Beacon Chain,到BNB Chain,再到BNB Greenfield ,三位一体的 BNB 生态格局正式形成。 ”在今年的2月1日,币安发布了分布式存储链BNB Greenfield,根据白皮书信息,它的特别之处在于其不仅具备基于SP&a…...
【SQL开发实战技巧】系列(十六):时间类型操作(上):日、月、年、时、分、秒之差及时间间隔计算
系列文章目录 【SQL开发实战技巧】系列(一):关于SQL不得不说的那些事 【SQL开发实战技巧】系列(二):简单单表查询 【SQL开发实战技巧】系列(三):SQL排序的那些事 【SQL开发实战技巧…...
JavaScript知识点总结
JavaScript 一、介绍: 1.JavaScript是一种专门在浏览器编译并执行的编程语言 2.JavaScript处理用户与浏览器之间请求问题 3.JavaScript采用【弱类型编程语言风格】对【面向对象思想】来进行实现的编程语言 二、弱类型编程语言风格 VS 强类型编程语言风格 …...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门  / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...
