一.启动概述

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

作者:京东科技 陈方林

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

Java NIO 图解 Netty 服务端启动的过程的更多相关文章

  1. Netty 服务端启动过程

    在 Netty 中创建 1 个 NioServerSocketChannel 在指定的端口监听客户端连接,这个过程主要有以下  个步骤: 创建 NioServerSocketChannel 初始化并注 ...

  2. Netty之旅三:Netty服务端启动源码分析,一梭子带走!

    Netty服务端启动流程源码分析 前记 哈喽,自从上篇<Netty之旅二:口口相传的高性能Netty到底是什么?>后,迟迟两周才开启今天的Netty源码系列.源码分析的第一篇文章,下一篇我 ...

  3. netty服务端启动--ServerBootstrap源码解析

    netty服务端启动--ServerBootstrap源码解析 前面的第一篇文章中,我以spark中的netty客户端的创建为切入点,分析了netty的客户端引导类Bootstrap的参数设置以及启动 ...

  4. 【Netty源码分析】Netty服务端bind端口过程

    这一篇博客我们介绍一下Netty服务端绑定端口的过程,我们通过跟踪代码一直到NIO原生绑定端口的操作. 绑定端口操作 ChannelFuture future = serverBootstrap.bi ...

  5. Netty服务端启动过程相关源码分析

    1.Netty 是怎么创建服务端Channel的呢? 我们在使用ServerBootstrap.bind(端口)方法时,最终调用其父类AbstractBootstrap中的doBind方法,相关源码如 ...

  6. JAVA RPC (九) netty服务端解析

    源码地址:https://gitee.com/a1234567891/koalas-rpc 企业生产级百亿日PV高可用可拓展的RPC框架.理论上并发数量接近服务器带宽,客户端采用thrift协议,服务 ...

  7. Netty源码分析(二):服务端启动

    上一篇粗略的介绍了一下netty,本篇将详细介绍Netty的服务器的启动过程. ServerBootstrap 看过上篇事例的人,可以知道ServerBootstrap是Netty服务端启动中扮演着一 ...

  8. Netty源码分析之服务端启动

    Netty服务端启动代码: public final class EchoServer { static final int PORT = Integer.parseInt(System.getPro ...

  9. 原理剖析-Netty之服务端启动工作原理分析(上)

    一.大致介绍 1.Netty这个词,对于熟悉并发的童鞋一点都不陌生,它是一个异步事件驱动型的网络通信框架: 2.使用Netty不需要我们关注过多NIO的API操作,简简单单的使用即可,非常方便,开发门 ...

  10. Netty源码解析 -- 服务端启动过程

    本文通过阅读Netty源码,解析Netty服务端启动过程. 源码分析基于Netty 4.1 Netty是一个高性能的网络通信框架,支持NIO,OIO等多种IO模式.通常,我们都是使用NIO模式,该系列 ...

随机推荐

  1. DataGridViewImageColumn 图片照片

    Private Sub BT_PHOTOADDRESS_Click(sender As Object, e As EventArgs) Handles BT_PHOTOADDRESS.Click Di ...

  2. LOTO示波器如何测试阻抗的频响曲线

    LOTO示波器如何测试阻抗的频响曲线 模块的输入输出端口,在电路分析上,一般简单表征为电阻来进行计算和分析.但多数情况下,这些端口并不是纯电阻的特性,更精确一些,它可能是电阻电容以及电感的组合,表现为 ...

  3. 使用android studio发布android与flutter混合开发项目

    一.生成androd签名证书 Android studio的Build > Grenerate Signed Bundle 选择apk 点击Create New 录入对应的签名信息:点击确定 对 ...

  4. kali系统安装redis步骤

    环境: 攻击机:Kali  5.16.0-kali7-amd64    192.168.13.78 靶机:   Kali  5.16.0-kali7-amd64    192.168.13.94 安装 ...

  5. element-ui中Select 选择器异步加载下一页

    场景 当我们使用 Select 选择器存放大量数据的时候. 会发现存在这么2个问题. 1.接口响应时间较长.(因为数据量较多,一次查询的所有)甚至有可能超时. 2.前端下拉框滑动卡顿. 这个时候们如何 ...

  6. Falcon 登陆 Hugging Face 生态

    引言 Falcon 是由位于阿布扎比的 技术创新研究院 (Technology Innovation Institute,TII) 创建的一系列的新语言模型,其基于 Apache 2.0 许可发布. ...

  7. 牛客题解-mixup2混乱的奶牛(状压dp)

    题解-mixup2混乱的奶牛 [原题连接](1026-mixup2混乱的奶牛_2021秋季算法入门班第八章习题:动态规划2 (nowcoder.com)) 题目描述 混乱的奶牛 [Don Piele, ...

  8. GC 分代回收算法

    GC 分代回收算法 1.首先了解JVM堆内存是如何分配的. 年轻代内部  生成区 和 S0 S1 的比例 默认情况下是 8:1 :1 堆内存和永久代存储的内容有区别:  堆内存主要存储的是 : 对象, ...

  9. 彻底解决各种浏览器访问不了GitHub问题(注意代理)

    如果有穿墙插件如Google助手  VPN  SS 之类别 有可能被全局代理 首先关闭这些软件 或者浏览器插件 假设,您的本地代理端口为:1080 ,打开git base窗口进行按下列的方式设置.(在 ...

  10. SQL Server中获取不同格式的日期

    select * from 表名 where Convert(varchar(100),日期字段,23)='2008-12-15' Convert函数的应用: Select CONVERT(varch ...