Netty「源码阅读」之怎么解决 Java 的 epoll 空轮询 bug

简介: Netty「源码阅读」之怎么解决 Java 的 epoll 空轮询 bug

前言

Java NIO中有一个著名的 bug epoll, 这个 bug 会导致Reactor线程被唤醒, 进行空轮询, 最终COU 100%爆满, 那么Netty是怎么解决epollbug 的呢

在上篇文章中我们有说过, NioEventLoop.run()方法是基于Selector的轮询方法, 在方法内部实现了死循环去获取网络IO事件并执行

也是在该方法中Netty巧妙地解决了epollbug, 接下来让我们定位到该方法


Netty 解决 epoll

在这个方法中, 我将重点的步骤进行了标注, 先说流程, 然后在进行针对性的讲解

  • 初始化selectCnt 这个变量是解决epoll的关键
  • 定义变量strategy, 他是int类型, 默认是0
  • 执行selectStrategy.calculateStrategy()方法获取当前网络IO事件数量
  • 根据strategy来执行不同的操作, 这个后面贴详细代码讲一下
  • 这个时候我们的变量selectCnt++
  • 我们会对当前执行的任务和strategy进行判断, 对selectCnt进行归零操作
  • 否则, 我们会对执行方法unexpectedSelectorWakeup()selectCnt进行边界值判断

网络异常,图片无法展示
|

Switch

switch中, 一共case了三个常量

  • SelectStrategy.CONTINUE: 继续, 直接跳过, 这里不做讲解
  • SelectStrategy.BUSY_WAIT: NIO不支持 BUSY_WIAT, 所以和 SELECT 是一样的
  • SelectStrategy.SELECT: 判断当前 IO事件 是否就绪, 如果没有就绪就让线程休息, 不进行唤醒

网络异常,图片无法展示
|

SelectStrategy.SELECT

具体判断线程是否要苏醒的地方是下面两个红框

网络异常,图片无法展示
|

unexpectedSelectorWakeup()方法

实际上解决空轮询问题的地方就是在这里

网络异常,图片无法展示
|

在这个方法中我们可以看到, 方法返回值是判断selectCnt是否大于静态变量SELECTOR_AUTO_REBUILD_THRESHOLD, 那么我们看一下这个变量的赋值过程

网络异常,图片无法展示
|

跟着序号看起, 先是定义了变量, 然后将selectorAutoRebuildThreshold赋值于SELECTOR_AUTO_REBUILD_THRESHOLD, 可以看到执行了SystemPropertyUtil.getInt方法, 这个方法是获取你配置文件中的值, 如果你的配置文件中没有进行配置, 那么就使用后面的默认值512

这也就是为什么, 我们经常看到说: 当Netty空轮询阈值是512

假设我们的selectCnt已经达到了512, 还会执行一个方法rebuildSelector();顾名思义, 重建Selector

网络异常,图片无法展示
|

这个方法的作用是将当前这个发生空轮训的selector上的selectedKeys挪到新建的selector选择器上,从而完美解决空轮训的问题

然后我们的unexpectedSelectorWakeup返回true, 回到之前的run()方法中可以看到, 作者将selectCnt重新赋值为了0, 所以作者也不算是解决了这个bug, 但是巧妙的将其绕过了

网络异常,图片无法展示
|

总结

总结就简单写写, 初始化变量selectCnt, 每次轮询进行++操作, 后面会将其进行归零, 如果没有归零selectCnt, 会执行unexpectedSelectorWakeup()方法, 如果达到了512, 会进行selector重建



宁轩
+关注
目录
打赏
0
0
0
0
2
分享
相关文章
Java注解的底层源码剖析与技术认识
Java注解(Annotation)是Java 5引入的一种新特性,它提供了一种在代码中添加元数据(Metadata)的方式。注解本身并不是代码的一部分,它们不会直接影响代码的执行,但可以在编译、类加载和运行时被读取和处理。注解为开发者提供了一种以非侵入性的方式为代码提供额外信息的手段,这些信息可以用于生成文档、编译时检查、运行时处理等。
106 7
[Java计算机毕设]基于ssm的OA办公管理系统的设计与实现,附源码+数据库+论文+开题,包安装调试
OA办公管理系统是一款基于Java和SSM框架开发的B/S架构应用,适用于Windows系统。项目包含管理员、项目管理人员和普通用户三种角色,分别负责系统管理、请假审批、图书借阅等日常办公事务。系统使用Vue、HTML、JavaScript、CSS和LayUI构建前端,后端采用SSM框架,数据库为MySQL,共24张表。提供完整演示视频和详细文档截图,支持远程安装调试,确保顺利运行。
65 17
|
29天前
|
【源码】【Java并发】【线程池】邀请您从0-1阅读ThreadPoolExecutor源码
当我们创建一个`ThreadPoolExecutor`的时候,你是否会好奇🤔,它到底发生了什么?比如:我传的拒绝策略、线程工厂是啥时候被使用的? 核心线程数是个啥?最大线程数和它又有什么关系?线程池,它是怎么调度,我们传入的线程?...不要着急,小手手点上关注、点赞、收藏。主播马上从源码的角度带你们探索神秘线程池的世界...
100 0
【源码】【Java并发】【线程池】邀请您从0-1阅读ThreadPoolExecutor源码
智慧产科一体化管理平台源码,基于Java,Vue,ElementUI技术开发,二开快捷
智慧产科一体化管理平台覆盖从备孕到产后42天的全流程管理,构建科室协同、医患沟通及智能设备互联平台。通过移动端扫码建卡、自助报道、智能采集数据等手段优化就诊流程,提升孕妇就诊体验,并实现高危孕产妇五色管理和孕妇学校三位一体化管理,全面提升妇幼健康宣教质量。
58 12
干货含源码!如何用Java后端操作Docker(命令行篇)
只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
Java智慧工地(源码):数字化管理提升施工安全与质量
随着科技的发展,智慧工地已成为建筑行业转型升级的重要手段。依托智能感知设备和云物互联技术,智慧工地为工程管理带来了革命性的变革,实现了项目管理的简单化、远程化和智能化。
55 5
SaaS云计算技术的智慧工地源码,基于Java+Spring Cloud框架开发
智慧工地源码基于微服务+Java+Spring Cloud +UniApp +MySql架构,利用传感器、监控摄像头、AI、大数据等技术,实现施工现场的实时监测、数据分析与智能决策。平台涵盖人员、车辆、视频监控、施工质量、设备、环境和能耗管理七大维度,提供可视化管理、智能化报警、移动智能办公及分布计算存储等功能,全面提升工地的安全性、效率和质量。
基于Java+SpringBoot+Vue实现的车辆充电桩系统设计与实现(系统源码+文档+部署讲解等)
面向大学生毕业选题、开题、任务书、程序设计开发、论文辅导提供一站式服务。主要服务:程序设计开发、代码修改、成品部署、支持定制、论文辅导,助力毕设!
建筑施工一体化信息管理平台源码,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
智慧工地云平台是专为建筑施工领域打造的一体化信息管理平台,利用大数据、云计算、物联网等技术,实现施工区域各系统数据汇总与可视化管理。平台涵盖人员、设备、物料、环境等关键因素的实时监控与数据分析,提供远程指挥、决策支持等功能,提升工作效率,促进产业信息化发展。系统由PC端、APP移动端及项目、监管、数据屏三大平台组成,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
127 7
基于 SpringBoot 和 Vue 开发校园点餐订餐外卖跑腿Java源码
一个非常实用的校园外卖系统,基于 SpringBoot 和 Vue 的开发。这一系统源于黑马的外卖案例项目 经过站长的进一步改进和优化,提供了更丰富的功能和更高的可用性。 这个项目的架构设计非常有趣。虽然它采用了SpringBoot和Vue的组合,但并不是一个完全分离的项目。 前端视图通过JS的方式引入了Vue和Element UI,既能利用Vue的快速开发优势,
192 13