首页 > 编程语言 >Netty源码学习2——NioEventLoop的执行

Netty源码学习2——NioEventLoop的执行

时间:2023-08-18 19:55:14浏览次数:57  
标签:NioEventLoop Netty 任务 源码 事件 IO 执行

系列文章目录和关于我

零丶引入

在《Netty源码学习1——NioEventLoopGroup的初始化》中,我们学习了NioEventLoopGroup和NioEventLoop的初始化,在下面netty服务端启动的demo中

image-20230818150757349

会在ServerBootStrap中指定Channel为Nio类型的Channel,然后启动的时候绑定端口,之前我们解释道NioEventLoop是事件循环,这里的事件是指客户端连接,数据准备就绪等IO事件,循环是指会有一个线程不断的处理任务。so 这篇我们一起看下NioEventLoop是如何产生IO事件并执行各种任务的。

一丶NioEventLoop的初始化

这部分在[Netty源码学习1——NioEventLoopGroup的初始化#第四节](Netty源码学习1——NioEventLoopGroup的初始化 - Cuzzz - 博客园 (cnblogs.com))中进行了说明,其中比较有趣的是Netty对JDK原生Selector的优化,将原本基于HashSet的SelectionKey集合,修改为基于数组的SelectionKey集合,优化了迭代和修改的效率,再次就不在过多赘述了。

二丶NioEventLoop的启动

NioEventLoop中存在一个run方法,该方法是一个死循环,这便是事件循环中的循环,它由一个线程专门去执行,我们先分析下NioEventLoop#run方法是什么时候开始执行的。

image-20230818160755962

如上分别是客户端和服务端启动部分的源码,在bind 和 connect中都会触发——Channel的初始化+Channel的注册。

  1. Channel的初始化:由对应的Factory进行创建(默认使用反射)

  2. Channel的注册:这里的注册将调用NioEventLoopGroup#register方法,

    image-20230818161332251

    这里自然是通过EventExecutorChooser#next方法选择一个NioEventLoop进行注册

    image-20230818161625569

    image-20230818161846194

    在excute方法中会将EventLoop#run方法包装成一个Runnable提交到线程池中,这里的线程池是被包装后的ThreadPerTaskExecutor,每一个任务的提交都会新建一个线程去执行

    image-20230818162111791

    因此可以任务NioEventLoop#run方法由一个线程单独去执行

三丶NioEventLoop#run

1.SelectStrategy控制循环

和Tomcat的Poller类似,NioEventLoop需要使用Selector去进行IO多路复用,Netty抽象出SelectStrategy使用其calculateStrategy来控制循环

image-20230818164523102

image-20230818174638767

其中selectNow即使用JDK Selector#selectNow方法进行非阻塞select

image-20230818174845727

DefaultSelectStrategy#calculateStrategy的逻辑是,如果当前EventLoop中存在任务那么直接返回就绪的就绪SelectionKey数目,如果不存哎任务,那么返回常量SELECT(-1),根据返回的数字会进入不同的分支。

image-20230818181617099

2.执行阻塞select

image-20230818183604408

NioEventLoop支持调度任务,因此内部使用了优先队列保存调度任务,并且调度任务具备一个deadlineNanos属性

image-20230818184201875

image-20230818184706084

3.执行任务

NioEventLoop支持ioRatio指定IO事件的处理事件,和其他任务执行时间的比例

image-20230818185819749

其中处理IO时间的部分涉及到Netty的ChannelPipeline的执行,这部分在后续的博客中进行讲解

3.1 runAllTasks

无参的runAllTask会在IO事件处理结束后执行,首先会将scheduledTaskQueue中的任务(未到执行时间的任务,or deadlineNanos早于当前时间的任务 不会转移到taskQueue)转移到taskQueue,然后执行taskQueue中的任务,执行完taskQueue的任务后,执行tailTasks中的任务

image-20230818191432339

3.2 runAllTasks(超时时间)

大流程和上面runAllTasks类似,依旧是将调度任务从scheduledTaskQueue转移到taskQueue,然后执行taskQueue任务,然后执行tailTasks中的任务

image-20230818192120835

感觉比较有趣的是,对调度任务的处理,移动到taskQueue后并不会再次判断其deadlineNanos和当前时间的关系,不会再关注其是否过期。

3.3 处理NIO空轮询的bug

Java NIO在linux下基于epoll,但是因为poll和epoll对于突然中断的连接socket会对返回的eventSet事件集合置为EPOLLHUP或者EPOLLERR,eventSet事件集合发生了变化,这会导致Selector会被唤醒,唤醒之后却没有感兴趣的事件,导致IO事件处理的循环不会执行,陷入到循环中.

image-20230818193354861

下面我们看看netty是如何处理此bug的

image-20230818193619887

image-20230818193934921

可以看到Netty通过重新构建Selector的方式去规避空轮询的bug,其中rebuildSelector最终调用rebuildSelector0,会将原本selector中的SelectionKey拷贝到新的selector,然后关闭旧的Selector

四丶总结

此节我们学习了NioEventLoop的执行原理,本质上还是通过Selector进行IO多路复用,理解了什么是事件循环,其中的事件指通过IO多路复用监听多路IO事件,循环是指循环的监听IO事件,并处理IO事件和其他任务,但是对于IO事件的处理我们并未做更多的学习,这部分将在下一篇中进行学习。

标签:NioEventLoop,Netty,任务,源码,事件,IO,执行
From: https://www.cnblogs.com/cuzzz/p/17641482.html

相关文章

  • 某电商平台电子产品用户购买行为研究-计算机毕业设计源码+LW文档
    摘要随着计算机和互联网的普及,搜索引擎成了人们常用的工具。通过搜索引擎来查询电商网站销售信息,搜索引擎首先对关键词进行分析,然后返回查询的结果。但是随着网络信息量的急速增长,产生了大量的垃圾信息和网络广告,使得查询结果越来越困难。针对这一问题,本系统通过对网络爬虫的分析......
  • IT行业招聘数据分析与岗位推荐系统-计算机毕业设计源码+LW文档
    内容摘要随着社会经济的快速发展,人们的生活水平得到了显著提高,但随之而来的社会问题也越来越多。其中最为显著的就是就业问题。为此,招聘信息的展示也变得越来越为重要。但是在大量的招聘信息中,人们在提取自己最想要的信息时变得不那么容易,对于应聘者也是如此。本系统通过对网络爬虫......
  • 基于Python的招聘网站爬虫及可视化的实现-计算机毕业设计源码+LW文档
    开发语言:Python框架:flaskPython版本:python3.7.7数据库:mysql5.7(一定要5.7版本)数据库工具:Navicat11开发软件:PyCharm浏览器:谷歌浏览器DROPTABLEIFEXISTSa6woc_zhaopinxinxi;/*!40101SET@saved_cs_client=@@character_set_client/;/!40101SETcharacter_set_cli......
  • 基于Redis实现关注、取关、共同关注及消息推送(含源码)
    微信公众号访问地址:基于Redis实现关注、取关、共同关注及消息推送(含源码)一、简介       实现用户之间的关注和取消关注、查询是否关注、共同关注及关注后消息采用feed方式推送及滚动分页查看效果等相关功能。利用redis里面的Set集合实现关注,取关,共同关注,消息推送等,结合Jav......
  • 金融行业招聘数据分析系统的设计与实现-计算机毕业设计源码+LW文档
    摘要随着社会经济的快速发展,人们的生活水平得到了显著提高,但随之而来的社会问题也越来越多。其中最为显著的就是就业问题。为此,招聘信息的展示也变得越来越为重要。但是在大量的招聘信息中,人们在提取自己最想要的信息时变得不那么容易,对于应聘者也是如此。本系统通过对网络爬虫的......
  • AOP源码解析:AspectJExpressionPointcutAdvisor类
    先看看AspectJExpressionPointcutAdvisor的类图再了解一下切点(Pointcut)表达式,它指定触发advice的方法,可以精确到返回参数,参数类型,方法名1packageconcert;23publicinterfacePerformance{4voidperform();5}AspectJExpressionPointcutAdvisor源码,官......
  • 直播平台源码之实现网络请求的方法
    直播平台源码开发中如果你不会网络请求,那么你开发的应用软件就是一具没有灵魂的枯骨。当你下载完软件后会要求你给与权限,否则就没办法使用,网络请求也需要对应的权限,否则就没法进行联网操作。在直播平台源码开发中首先在AndroidManifest.xml文件中添加网络请求权限要在manifest......
  • 如何在视频直播app源码开发中实现开屏广告功能
    APP开屏广告就目前来说是一个很常见的广告形式,我们现在打开各个APP几乎都会有开屏广告的身影,开屏广告也成了吸引用户注意力和实现盈利的主要方式,所以在视频直播app源码开发,开屏广告功能就显得尤为重要。一、视频直播app源码之开屏广告作用:广告、营销推广界面组成:广告、跳过(倒计......
  • 悬赏平台APP系统源码
      悬赏平台APP软件是一款在线上做任务,拉新,充场的软件,任何一个用户在平台上注册账号,发布任务,领取任务并获得佣金。本文就一悬赏任务APP软件对功能上的事项进行分析,看看都有哪些功能。  1.任务源  悬赏平台APP展示者所有的任务平台类型,任务做法流程,任务要求,有充场,拉新,......
  • CentOS7源码安装JDK8☘️
    1.下载jdk  Java版本支持路线图 Java9、Java10、Java12、Java13、Java14、Java15和Java16均为短期版本,建议不要使用以上版本。官网下载如有旧版本请先卸载openjdk:[root@localhost~]#yumerase`rpm-qa|grepopenjdk`-y2.解压安装:[root@localhost~]#tarxvz......