乐趣区

关于后端:Java-NIO-图解-Netty-服务端启动的过程-京东云技术团队

一. 启动概述

理解整体 Netty 罕用的外围组件后,并且比照了传统 IO 模式。在比照过程中,找到了传统 IO 对应 Netty 中是如何实现的。最初咱们理解到在 netty 中罕用的那些组件。

本文在理解下这些外围组件的前提下,进一步理解组件如何在整个服务器启动过程如何被创立,如何组件之间配合来应用。首先也是先理解下大略服务端的启动过程,并且在理解过程中咱们带着本人的问题去在学习过程中探寻答案。

1.1 启动概述

1.2 启动问题

  1. netty 服务端启动是如何设置非阻塞模式的?
  2. 服务端启动后事件是如何注册到 selector 上?

二. 启动详述

2.1 channel 创立

还是一样首先在 channel 创立过程大略有哪些过程

  • bind
  • initAndRegister
  • 默认构造函数创立 channel

具体调用关系

时序图中从 1,2,3 步都好了解。

2.1.1 创立 channelFactory

从类的反射失去 channel 这里是一个关键点须要阐明:

图中间接应用 channelFactory 来实现了 channel 的实例化. 那么就按图索骥这个 channelFactory 是什么时候赋值的。

图中咱们一步步找到 channelFactory 的门路。咱们再看第三步是谁调用了
channel(Class<? extends C> channelClass) 创立了 channelFactory。最初发现咱们在 bootstrap 设置 channel 属性的时候设置了 channelFactory。

走到这里咱们才真正进入晓得在 bootstrap 设置 NioServerSocketChannel。并利用 NioServerSocketChannel 创立。

上述步骤咱们小结一下。通过设置 bootstrap 的 Channel 属性来设置服务端 NioServerSocketChannel 生成了 channelFactory。channelFactory 来被动调用传入的 class 来结构 channel。

2.2.2 NioServerSocketChannel 默认构造函数创立 Channel

从上图中咱们晓得该结构工厂是调用类的构造函数来进行初始化,通过代码中咱们晓得结构类为 NioServerSocketChannel。那么就看下 NioServerSocketChannel 结构过程。

先上来还是看下整体步骤:

通过默认的 newSocket 办法创立了 jdk 底层的 channel,而后通过 Channel 的配置了 channel 的 id,对应 channel 底层的读写 unsafe 组件,channel 对应的逻辑解决 pipeline,
最初通过 configureBlocking 设置 channel 为非阻塞模式【答复了咱们第一个问题】。
第三步:通过 channelConfig 设置一些 tcp 层面的设置

至此 channel 创立实现

2.2 channel 初始化

通过下面 2.1 整个 channel 曾经创立实现。第二大步在创立 channel 的根底上,给 channel 做一些属性配置。

上图设置用的属性 对应到代码中 为如下的代码

这里均为一些本人的属性和配置的设置,至此 channel 的创立和初始化实现。这里的配置用以客户端新建连贯时进行设置。

2.3 selector 注册

还是先整体看下 整个 selector 流程,是如何将 channel 注册到 selector 上。

ps: 以上代码流程须要一层层通过断点形式进行跟踪。

第一步:AbstractBootStrap register 入口

以上的步骤实现 channel 的创立和初始化,通过 initAndRegister 外部办法来实现 selector 挂载.

第二步:调用

io.netty.channel.MultithreadEventLoopGroup#register(io.netty.channel.Channel)

register 办法中通过 next 办法获取下一个能够调用 EventLoop 来调用它的 register 办法

第三步:调用

io.netty.channel.SingleThreadEventLoop#register(io.netty.channel.Channel)

调动 channel.unsafe.register 办法获取 channel 底层操作,并调用 unsafe 的 register 办法

第四步: 通过调用 abstract Nio Channel 将 channel 注册到 eventLoop 的 selector 中【第二个问题的答案】,并将以后 channel 作为 attache 与 socket channel 关联。

实现对应的 selector 和 channel 绑定之后如果有相应的事件回调会进行事件回调操作,这里需要的话须要继承 ChannelInboundHandlerAdapter 中对应的办法 channelRegistered,channelActive。

至此 nio channel 通过 java 底层的 socketchannel 绑定 到指定的 selector,实现 selector 与 niochannel 的注册过程。

2.4 端口绑定

根本步骤

第一步:底层端口 channel 绑定

第二步:最终调用 AbstractNioChannel doBeginRead 办法。

激活 channel 并向 selector 注册 read 事件。

三 . 总结

整体理解到 netty 服务端的启动过程。

  1. 通过 NioServerSocketChannel 的 channelFactory 创立 channelFactory 办法
  2. channelFactory 通过反射调用 nioServerSocketChannel 构造函数。创立 channel 对象
  3. channel 通过 NioServerSocketChannelConfig 将自定义的 option,attr,handler 设置实现。
  4. abstract Nio Channel 调用 register 办法实现 selector 和 channel 的绑定
  5. 最终调用 java channel 进行端口绑定并向 selector 注册 read 事件

整体 netty 服务端启动实现。

作者:京东科技 陈方林

起源:京东云开发者社区 转载请注明起源

退出移动版