Netty对Channel事件的处理以及空轮询Bug的解决

继续上一篇Netty文章,这篇文章主要分析Netty对Channel事件的处理以及空轮询Bug的解决

当Netty中采用循环处理事件和提交的任务时

由于此时我在客户端建立连接,此时服务端没有提交任何任务

此时select方法让Selector进入无休止的阻塞等待

此时selectCnt++进行一次计数,ioRatio用来设置处理非事件任务所占总事件的比例

紧接着进入processSelectedKeys方法内部,处理连接事件

由于NioEventLoop中维护了一个Selector,这里的SelectedKeys是对原始Selector中的SelectedKeys的一种优化,后续文章会总结Netty做的优化

这段代码作用就是获得到对应事件,然后通过附件的方式拿到NioServerSocketChannel

紧接着利用NioServerSocketChannel中的unsafe类完成消息的写出的读入

调用unsafe的read方法后,通过read方法中的doReadMessages拿到Java ServerSocketChannel建立的SocketChannel

拿到SocketChannel后,创建一个NioSocketChannel,并创建对应的pipleline,config等等和NioServerSocketChannel一样。然后把它暂存在一个List集合buf中

紧接着调用NioServerSocketChannel的pipleline方法出发read事件,这里提醒一下pipleline的组成一次是head,logging,acceptor,tail组成

此方法内部其实就是不断的查找下一个Handler,调用Read方法

并且由于一些任务比较耗时为了不阻塞链接线程可以使用自己设置线程组

当轮到acceptor方法处理时

注意:这里的childHandler是我们在server端最开始的strap代码时填入childHandler属性中的Handler,同时下方的childGroup就是server端最开始的childNioEventLoopGroup

接下来register方法内部就是我们上一篇文章讲到的进行线程切换,把NioSocketChannel以附件的形式绑定到SocketChannel。由于每个NioEventLoop都维护了一个Selector,同时把SocketChannel注册到(child)NioEventLoopGroup中的NioEventLoop中的Selector接着继续循环监听事件处理提交的任务。分析到这里我们可以理解Netty的基本线程模型了

接下来连接事件处理完毕,BossGroup该处理普通任务了

可以看到ioRation是控制所占用时间的比例的

而selectCnt是为了避免在Linux中导致selector不阻塞从而进行计数,当超过512时就认为出现bug,Netty解决方法就是重新创建一个Selector,并把原始信息复制一份。

接下来我们研究数据的发送和读写

相关推荐
沐知全栈开发2 小时前
HTML DOM 访问
开发语言
llwszx3 小时前
深入理解Java锁原理(一):偏向锁的设计原理与性能优化
java·spring··偏向锁
脑袋大大的3 小时前
JavaScript 性能优化实战:减少 DOM 操作引发的重排与重绘
开发语言·javascript·性能优化
云泽野4 小时前
【Java|集合类】list遍历的6种方式
java·python·list
二进制person4 小时前
Java SE--方法的使用
java·开发语言·算法
OneQ6664 小时前
C++讲解---创建日期类
开发语言·c++·算法
小阳拱白菜5 小时前
java异常学习
java
码农不惑5 小时前
2025.06.27-14.44 C语言开发:Onvif(二)
c语言·开发语言
FrankYoou6 小时前
Jenkins 与 GitLab CI/CD 的核心对比
java·docker
麦兜*6 小时前
Spring Boot启动优化7板斧(延迟初始化、组件扫描精准打击、JVM参数调优):砍掉70%启动时间的魔鬼实践
java·jvm·spring boot·后端·spring·spring cloud·系统架构