想统计Netty的一轮事件循环的耗时,该怎么做?

原博文,点击这里

将NioEventLoop的整个处理异步任务的过程和设计思想进行了拆解,其实还漏了一个方法,下面重点分析一下。

回忆Netty的线程封装,重复印象,如下是NioEventLoop的继承图:

在这里插入图片描述

NioEventLoop的父类SingleThreadEventLoop里其实还有一个队列叫tailTasks,如下黄线处,它也被初始化为了一个MPSCQ:
在这里插入图片描述

tailTasks,单看它的名字就能猜出来,这是一个负责收尾任务的MPSCQ。下面看它在哪里被使用了,在SingleThreadEventLoop发现如下代码:
在这里插入图片描述

即方法executeAfterEventLoopIteration(task)。看方法名也能知道,这个方法的执行是在EventLoop的run循环一次之后被调用。这个方法本身没什么特别的,就是收尾的MPSCQ的任务聚合——用户将自定义的异步任务封装为task,调用它就可以将task添加到tailTasks,那么该队列到底何时会被执行呢?回忆NioEventLoop的runAllTasks方法:
在这里插入图片描述

两个红框处都调用了同一个方法:afterRunningAllTasks(),这个方法最终会执行tailTasks,去执行里面的收尾任务,执行时机有两个:

  • 1、EventLoop事件循环的一轮runAllTasks结束,即for循环退出需要做一次善后处理

  • 2、如直接从MPSCQ取出的task为null,那么也表明本轮runAllTasks结束,也要调用它做善后。

以上,其实调用时机可以归纳为一个,即EventLoop事件循环的一轮runAllTasks结束后,执行收尾任务。

简单看下这个afterRunningAllTasks()的内部实现:
在这里插入图片描述

内部调用到类io.netty.util.concurrent.SingleThreadEventExecutor的runAllTasksFrom方法:
在这里插入图片描述

以上,可以清晰的看到,runAllTasksFrom的工作就是取出tailTasks里的任务,并将其全部执行完,类似runAllTasks,它仍然是一个反复取出队列里的任务执行的逻辑。

综上,NioEventLoop可通过executeAfterEventLoopIteration(task)方法,向tailTasks队列添加收尾的异步任务,比如一些需要在一轮事件循环后执行的任务,就像标题说的,用户想统计执行一次事件循环花了多长时间就可以调用此方法将自己实现的统计业务封装为task在提交给NioEventLoop线程,当NIO线程执行完一次事件循环,就会自动执行这个task。

举个例子,如下是我之前写的一个RPC框架的服务器代码片段:
在这里插入图片描述

我在一个自定义的入站处理器里,通过channelRead0的参数——ctx,也就是前面总结流水线图像时,说到的双向链表的节点对象,拿到当前Channel绑定的eventloop,然后将其向上转换为SingleThreadEventLoop,在去调用它的executeAfterEventLoopIteration方法,异步的添加一个收尾的任务,这个收尾任务会在当前Channel绑定的NIO线程,一轮事件循环后才被执行,任务内容是简单记录被执行的次数,后续即可通过观察日志来确定一轮事件循环的时间间隔。PS. 其实使用普通int即可,因为全程是NIO线程执行。

启动服务器和客户端后,期间两者会有一个欢迎消息的来回,接着是心跳包,如下打印:
在这里插入图片描述

日志细节就不放了,这样就能通过日志的打印间隔,估算一些业务处理的耗时,这个耗时比单纯在channelRead这种方法里写要更准确一些,因为它能统计上NIO线程轮询I/O事件,处理I/O事件,以及其它业务逻辑的时间。可以辅助全面评估整个服务器架构设计的性能盲点。

不过需要注意的是,Netty将executeAfterEventLoopIteration方法标记了@UnstableApi:
在这里插入图片描述

@UnstableApi是Netty自己定义的注解,意思是表明某个API不是稳定的,可能在后续版本里删除,如果线上业务有依赖这样的方法,那么在升级Netty版本时,需要注意这一点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值