Java NIO 图解 Netty 服务端启动的过程 | 京东云技术团队

京东云开发者
• 阅读 377

一.启动概述

了解整体Netty常用的核心组件后,并且对比了传统IO模式。在对比过程中,找到了传统IO对应Netty中是如何实现的。最后我们了解到在netty中常用的那些组件。

Java NIO 图解 Netty 服务端启动的过程 | 京东云技术团队
本文在了解下这些核心组件的前提下,进一步了解组件如何在整个服务器启动过程如何被创建,如何组件之间配合来使用。首先也是先了解下大概服务端的启动过程,并且在了解过程中我们带着自己的问题去在学习过程中探寻答案。

1.1 启动概述

Java NIO 图解 Netty 服务端启动的过程 | 京东云技术团队

1.2 启动问题

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

二.启动详述

2.1 channel 创建

还是一样首先在channel创建过程大概有哪些过程

  • bind

  • initAndRegister

  • 默认构造函数创建channel

具体调用关系
Java NIO 图解 Netty 服务端启动的过程 | 京东云技术团队
时序图中从1,2,3步都好理解。

2.1.1 创建channelFactory

从类的反射得到channel这里是一个关键点需要说明:

Java NIO 图解 Netty 服务端启动的过程 | 京东云技术团队
图中直接使用channelFactory来实现了channel的实例化.那么就按图索骥这个channelFactory是什么时候赋值的。

Java NIO 图解 Netty 服务端启动的过程 | 京东云技术团队

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

Java NIO 图解 Netty 服务端启动的过程 | 京东云技术团队

走到这里我们才真正进入知道在bootstrap设置NioServerSocketChannel。并利用NioServerSocketChannel创建。
Java NIO 图解 Netty 服务端启动的过程 | 京东云技术团队

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

2.2.2 NioServerSocketChannel默认构造函数创建Channel

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

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

Java NIO 图解 Netty 服务端启动的过程 | 京东云技术团队
通过默认的newSocket方法创建了jdk底层的channel,然后通过Channel的配置了channel的id,对应channel底层的读写unsafe组件,channel对应的逻辑处理pipeline,
最后通过configureBlocking设置channel为非阻塞模式【回答了我们第一个问题】。
第三步:通过channelConfig设置一些tcp层面的设置

至此channel创建完成

2.2 channel 初始化

通过上面2.1 整个channel已经创建完成。第二大步在创建channel的基础上,给channel做一些属性配置。

Java NIO 图解 Netty 服务端启动的过程 | 京东云技术团队

Java NIO 图解 Netty 服务端启动的过程 | 京东云技术团队
上图设置用的属性 对应到代码中 为如下的代码

Java NIO 图解 Netty 服务端启动的过程 | 京东云技术团队
这里均为一些自己的属性和配置的设置,至此channel的创建和初始化完成。这里的配置用以客户端新建连接时进行设置。

2.3 selector 注册

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

Java NIO 图解 Netty 服务端启动的过程 | 京东云技术团队

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

第一步:AbstractBootStrap register 入口

Java NIO 图解 Netty 服务端启动的过程 | 京东云技术团队

以上的步骤完成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关联。

Java NIO 图解 Netty 服务端启动的过程 | 京东云技术团队

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

Java NIO 图解 Netty 服务端启动的过程 | 京东云技术团队

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

2.4 端口绑定

基本步骤

Java NIO 图解 Netty 服务端启动的过程 | 京东云技术团队

Java NIO 图解 Netty 服务端启动的过程 | 京东云技术团队

第一步:底层端口channel绑定

Java NIO 图解 Netty 服务端启动的过程 | 京东云技术团队

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

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

Java NIO 图解 Netty 服务端启动的过程 | 京东云技术团队

三 .总结

整体了解到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服务端启动完成。

作者:京东科技 陈方林

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

点赞
收藏
评论区
推荐文章
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
3年前
Netty 启动过程源码分析 (本文超长慎读)(基于4.1.23)
前言作为一个Java程序员,必须知道Java社区最强网络框架Netty,且必须看过源码,才能说是了解这个框架,否则都是无稽之谈。今天楼主不会讲什么理论和概念,而是使用debug的方式,走一遍Netty(服务器)的启动过程。1\.demo源码楼主clone的netty的源码,值得一提
Wesley13 Wesley13
3年前
vcsa6.5安装部署配置(vSphere vsan 6.5)
首先您最好先了解下vcenter和vcsa是啥:VMwareVsphere几个不同的组件(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fmhsj.net%2F50.html)esxi是在物理服务器安装的服务端,所有虚拟机是安装再esxi里面的,是服务端;vcent
Wesley13 Wesley13
3年前
VBox 启动虚拟机失败
在Vbox(5.0.8版本)启动Ubuntu的虚拟机时,遇到错误信息:NtCreateFile(\\Device\\VBoxDrvStub)failed:0xc000000034STATUS\_OBJECT\_NAME\_NOT\_FOUND(0retries) (rc101)Makesurethekern
Stella981 Stella981
3年前
Netty源码分析(二):服务端启动
上一篇粗略的介绍了一下netty,本篇将详细介绍Netty的服务器的启动过程。ServerBootstrap看过上篇事例的人,可以知道ServerBootstrap是Netty服务端启动中扮演着一个重要的角色。它是Netty提供的一个服务端引导类,继承自AbstractBootstrap。Serv
Stella981 Stella981
3年前
Netty之缓冲区ByteBuf解读(一)
!(https://oscimg.oschina.net/oscnet/up6de4d71f462d9846befe00ec6505125a928.JPEG)\Netty在数据传输过程中,会使用缓冲区设计来提高传输效率。虽然,Java在NIO编程中已提供ByteBuffer类进行使用,但是在使用过程中,其编码方式相对来说不太友好,也
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django组件——cookie与session
Django组件——cookie与session<fontcolor00bff一、会话跟踪技术</font<fontcolorff7f501、什么是会话跟踪技术</font先了解一下什么是会话。可以把
Stella981 Stella981
3年前
Netty 服务端启动过程
  在Netty中创建1个NioServerSocketChannel在指定的端口监听客户端连接,这个过程主要有以下 个步骤:1.创建NioServerSocketChannel2.初始化并注册NioServerSocketChannel3.绑定指定端口  首先列出一个简易服务端的启动代码:public
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_