在上一章中,我们介绍了在Netty中,我们可以使用Kequeue或Epoll来实现更有效的本机传输方法。
本章将以Kequeue为例,在深度讨论中讨论。
在上面介绍的示例中,有几个关于kqueue的类,包括Kqueueeventloopgroup,Kqueueserersocketchannel和Kqueuesocketchannel。通过简单的替换并添加相应的依赖性,我们可以轻松地服务普通的Nio网络。
是时候揭示kqueue的秘密了。
Eventloop和EventloopGroup用于接收事件和事件处理。LET查看KqueueeventloopGroup的定义:
作为一个多线ReadeventloopGroup,还必须实现一种纽子方法来创建child eventloop.in kqueueeventloopgroup,除了构造函数外,其他实施方法是newchild:newchild:
Newchild中的所有参数均在Kqueueeventloopgroup的构造函数中传递。
此外,我们需要在使用KqueueeeeVentloopGroup之前确保系统中的kqueue可用。该判断是通过呼叫来实现的。
kqueue.sureavailable首先确定是否定义了系统属性。io.netty.transport.nonative。如果是固定的,则意味着本地运输是禁用的,并且将来无需判断。
如果未定义io.netty.transport.nonative,则您将打电话给试图从本机中获取kqueue fileedScriptor。如果上述采集过程中没有异常,则意味着本机方法中存在kqueue,我们可以继续使用它。
以下是Kqueue可用的代码:
Kqueueeventloop是由Kqueueeventloopgroup创建的,以执行特定的IO任务。
让我们看一下Kqueueeventloop的定义:
无论是Nio,Kqueue还是Epoll,由于更高级的IO技术,他们使用的EventLoop都是Singlethreadeventloop,这意味着使用单线就足够了。
像Kqueueeventloopgroup一样,Kqueueeventloop还需要确定当前的系统环境是否支持Kqueue:
如上一节所述,Kqueueeventloopgroup将调用Kqueueeventloop构造函数返回Eventloop对象。让我们看一下Kqueueeventloop的构造函数:
Maxevents传输了该Kqueueeeeventloop可以接受的最大事件。如果MaxEvents = 0,则可以动态扩展Kqueueeventloop的事件容量,最大值为4096。否则,Kqueueeventloop的事件容量无法扩展。
Maxevents用作数组的大小来构建变更和eventlist。
Kqueueeventloop还定义了一个名为“通道”的地图,该地图用于保存注册的通道:
让我们看一下频道的添加和远程方法:
您可以看到添加和删除是AbstractKqueueUeUeUeUeUeeechannel。在以下各章中,我们将详细解释Kqueuechannel。在这里,我们只需要知道频道映射中的密钥是Kequeue中归档器的INT值。
让我们看一下Eventloop中最重要的运行方法:
它的逻辑是首先使用selectStrategy.calculatingrategy来获得当前的选择策略,然后确定是否基于策略的值执行processReady方法,并最终执行RunallTasks以执行要从任务队列执行的任务。
selectStrategy.calculatestrategy用于确定当前的选择状态。默认情况下有三个州,即:选择,继续,忙碌。
表示当前IO的块状态或当前IO的状态以及IO循环的状态公共状态。BUSY_WAIT是一种非块IO拉。kqueue不支持它,因此会选择后备。
除这三个状态外,计算仪表板还将返回正值,以指示要执行的任务数量。
在运行方法中,如果选择了策略的结果,则本机。KeventWait方法最终将调用当前事件的事件数量,并将Ready的事件放入KqueueeventArray的EventList。
如果准备事件的数量大于零,则将调用预制方法来宣布这些事件。
如何处理它?以下是处理的核心逻辑:
此处的FD是从EventList中读取的:
根据EventList的FD,我们可以从通道中获取相应的kqueuechannel,然后根据事件的过滤器状态确定Kqueuechannel的特定操作,该事件已编写,已读取或读取。
最后一个是执行RunallTasks方法。RunallTasks的逻辑非常简单,也就是说,从Taskqueue读取任务,然后执行。
Kqueueserversocketchannel是服务器上使用的频道:
kqueueserversocketchannel从Abstractkqueueserverververververververchanl继承。除了构建功能外,最重要的方法是纽奇渠道:
此方法用于创建一个新的儿童通道。从上面的代码中,我们可以看到生成的子频道是Kqueuesocketchannel的实例。
它的构造函数接受三个参数,即父频道,bsssocket和inetsocketAddress。
此处的FD是插座接受AcceptedAdress的结果:
以下是Kqueuesocketchannel的定义:
Kqueuesocketchannel还具有一个特征,是支持TCP快速键盘。它的本质是调用BSDSOCET的连接方法来建立数据,同时建立连接:
以上是Kqueueeventloop和Kqueuesocketchannel的详细介绍。基本上,它与Nio并没有太大不同,但是性能很棒。
有关更多内容,请参阅http://www.flydean.com/53-1-- netty-kqueue-transport/
最受欢迎的解释,最深的干货,最简单的教程,您不知道的许多技巧正在等待您发现!
欢迎注意我的公共帐户:“程序的事情”,了解技术并更好地了解您!
原始:https://juejin.cn/post/7103037223775240205