Netty服务端启动流程分析

简介: Netty服务端启动流程分析

前言

这是我 Netty源码阅读 活动的第三篇文章, 本篇开始带领大家去攻读ServerBootstrap.bind()方法, 在第一篇文章我带领大家学习了怎么设置Nettybacklog队列, 第二篇文章我们一起学习了启动Netty的配置详情, 感兴趣的可以去看一看, 链接贴在下面了

我的源码版本是跟着本次活动来的, 如果想跟着走一遍的建议使用同一个仓库, git命令如下

git clone https://github.com/arthur-zhang/netty-study.git
复制代码

图片看不清的, 点一下能放大, 应该不是只有我最近才知道吧.....

1 启动 bind() 方法

网络异常,图片无法展示
|

以 debug 的形式启动项目, 且在 bind 方法打断点

网络异常,图片无法展示
|

进入bind方法, 这里调用了InetSocketAddress类的构造方法, 他的作用是判断我们传入的这个端口是否正确

网络异常,图片无法展示
|

我们可以看到一共有四个bind方法, 最后都会进入到最后一个, 这就是我们常用的方法重写, 相同方法名, 参数不同, 实现相同的功能, 更方便我们多场景的调用

接下来我们进入 doBind()方法看一看, 这也是主要的的实现

validate(); 方法是对参数进行校验的, 可以无视掉

ObjectUtil.checkNotNull() 方法也一样的, 判断参数是否为空

2 doBind() 方法

网络异常,图片无法展示
|

刚好一屏放得下, 不然还不知道要怎么搞

简单说说doBind()方法都做了什么, 其实各种方法的命名是真的牛批, 一目了然

  • 先是进行初始化和注册
  • 取出channel
  • 判断中途是否出现报错
  • 判断初始化注册是否成功
  • 成功执行doBind0方法
  • 失败继续判断是否有报错, 有就抛异常, 没有就执行doBind方法

咱就说, 过了三天我才想起来doBind0方法忘记讲了....Netty之服务启动且注册成功之后 - 掘金 (juejin.cn)

接下来我们一起学习一下initAndRegister()方法

3 initAndRegister() 方法

网络异常,图片无法展示
|

首先可以看到, 先是创建了一个channel, 再通过channel = channelFactory.newChannel();为其进行赋值

channelFactory的类型是ReflectiveChannelFactory, 在我们执行ServerBootstrap.chennel()方法的时候就将其初始化了, 具体可以看一下我上一篇文章: Netty服务端初始化详解

网络异常,图片无法展示
|

ctrl+f搜索工厂, 或者通过标题点进去都可以

3.1 ReflectiveChannelFactory.newChannel() 方法

网络异常,图片无法展示
|

这是channelFactory.newChannel()的具体实现, 可以看到他就是实例化了传入的channel对象

3.2 init()

网络异常,图片无法展示
|

init(channel)方法是AbstractBootstrap抽象类的一个抽象方法, 该方法一共有两个实现, 分别是客户端Bootstrap和服务端ServerBootstrap, 参数就是上一步实例化好的channel对象

我们分析的主要是服务端, 那直接点进ServerBootstrap的实现就可以了

网络异常,图片无法展示
|

init方法中进行了各种初始化操作, 接下来我们挨个剖析

3.2.1 setChannelOptions(channel, newOptionsArray(), logger);

顾名思义设置channeloptions

网络异常,图片无法展示
|

点进了setChannelOptions方法可以看到, 他就是遍历了入参的options然后在下面的setChannelOption方法中将其加入到channel.config().setOption中, 那么我们回头看一下调用这个方法时传入的第二个参数是什么

网络异常,图片无法展示
|

网络异常,图片无法展示
|

可以看到, 他就是将当前的options属性进行了转换然后就传过来了, 如果看过我上一篇文章的小伙伴那肯定对options有些熟悉, 我们是在启动类那里对ServerBootstrap执行过option方法的时候进行配置的

网络异常,图片无法展示
|

网络异常,图片无法展示
|

那么setChannelOptions(channel, newOptionsArray(), logger);方法的作用我们也就知道了, 他就是对传入的option属性进行遍历配置, 不同环境不同的值进行不同的处理, 在上一篇文章中我也对常用的几种属性进行了讲解:  Netty服务端初始化详解

3.2.2 setAttributes(channel, newAttributesArray());

网络异常,图片无法展示
|

这个方法我理解的真不透彻, 只能看出来是把当前的属性attr遍历赋值给channel, 是真没用过, 我也是Netty初学者, 见谅, 后面如果有更深入的理解我在补充..

网络异常,图片无法展示
|

attr属性的设置还是在启动类那里, 通过ServerBootstrap.attr()进行, 作用是给服务端通道绑定自定义属性

小声逼逼: 截图之后才看到忘写分号了...

3.2.3 addLast() 方法

网络异常,图片无法展示
|

上面都是一些获取属性的方法, 忽略他, 直接看红框部分

网络异常,图片无法展示
|

所以我们要仔细看的就上面两个红框部分了, 首先是添加config.handler(), 这个上一篇文章也说过了, 是通过ServerBootstrap.handler()方法设置的, 所以直接就是把handler放入到addList

网络异常,图片无法展示
|

第二个红框部分, 是异步调用了ServerBootstrapAcceptor类的构造方法, 传入之前查询到的几个参数, 进行了初始化操作

小知识: 匿名内部类中传参要用final修饰

3.2.4 init()方法总结

所以我们看在init()方法中都做了什么事:

  • option进行初始化
  • attr进行初始化
  • handler添加到addLast
  • 初始化ServerBootstrapAcceptor

所以, 本次源码活动 - Netty部分的任务二也就完成了

网络异常,图片无法展示
|

如果看到这里了, 我觉得可以安排一个 👍

3.3 config().group().register(channel)

回到我们的initAndRegister方法

网络异常,图片无法展示
|

如果你直接Ctrl+鼠标左键点入register方法的话, 你会发现这个方法是一个接口, 他有四个实现, 那么怎么找到这个实现呢

网络异常,图片无法展示
|

首先我们要找到我们的config.group()是指的什么, 在上一篇文章中, 我们的配置类详解有讲到过serverBootstrap.group()方法, 就是来设置这个类的, 那我们就可以看到这个方法他的类是什么了, 直接执行相应的实现不就可以了吗

记住第一个红框里面的group类具体是什么, 下张图见分晓

网络异常,图片无法展示
|

这里贴一张NioEventLoopGroup类的继承实现图, 可以看到对应register的方法实现类找到了MultithreadEventLoopGroup

可能有小伙伴第一反应是去找EventLoopGroup这个类, 建议每次直接找实现类, 然后看继承实现图, 例如本次我们就会发现EventLoopGroup类根本就是一个接口类, 何谈实现register方法呢

网络异常,图片无法展示
|

最后我们找到了MultithreadEventLoopGroup类实现的register方法, 发现他又调用了父类的next方法..

我们知道, 我们现在的groupNioEventLoopGroup的对象, 在NioEventLoopGroup里面初始化了跟传入线程数目相同的NioEventLoopGroup对象, next()方法就是用来计算出下一个选用的NioEventLoopGroup对象是哪个

网络异常,图片无法展示
|

因为我们是打断点的形式, 所以一直F5就可以到最后执行的regiter方法了, 在这里可以看到他实例化了一个DefaultChannelPromise对象

我们的快捷键可能不一样, 具体情况具体分析

网络异常,图片无法展示
|

3.3.1 register具体实现 register0

网络异常,图片无法展示
|

继续往下走, 我们会到真正的register方法的实现类

网络异常,图片无法展示
|

在真正的实现类中,我们会发现他最终都会执行到register0方法

网络异常,图片无法展示
|

3.3.2 doRegister()

网络异常,图片无法展示
|

但是当我们点到doRegister()方法的时候会发现它里面实现是空的, 这个时候不要慌, 翻译大法好

网络异常,图片无法展示
|

可以看到, 他说子类可以覆盖这个方法, 那么我们就去找他的子类

网络异常,图片无法展示
|

因为我们打断点了, 所以一直按F5, 继续下一步就可以了, 最后我们会来到AbstractNioChannel类的doRegister方法, 这个就是最后执行的实现

后面是回家写的了, idea样式有些变化, 大家见谅一下

这一步主要的作用是: 用给定的Selector注册当前Channel, 返回selectionKey, 也就是在这里进行了注册操作, 因为在走下去就是 JDK 的 nio 的方法了, 就不继续看了

网络异常,图片无法展示
|

这里注意一下传入的第三个参数为 0

3.3.2.1 pipeline.fireChannelRegistered();

pipeline里面维护的是ChannelHandler列表, 在注册之后会调用ChannelInboundHandlerchannelRegistered方法

例如我在这个位置打上断点, LoggingHandler就会被打印

网络异常,图片无法展示
|

3.2.3 isActive() 方法

网络异常,图片无法展示
|

这是一个多态方法:

  • 对于服务器: 用来判断监听是否启动
  • 对于客户端: 用来判断TCP是否连接成功

网络异常,图片无法展示
|

当我使用TCP工具进行连接我们的Netty服务器的时候, 该方法返回true

3.2.4 pipeline.fireChannelActive()

网络异常,图片无法展示
|

这个方法的实现就是客户端第一次注册的时候会触发ChannelInboundHandlerchannelActive方法, 通知ChannelHander已经注册完成, 这时就会回调他们的channelActive方法

网络异常,图片无法展示
|

还是上面的例子, 当用TCP工具连接执行完该方法之后如截图所示

总结

  • 在启动项目之后会调用serverBootstrapbind方法
  • 通过initAndRegister方法对channel进行初始化和注册
  • channelFactory工厂里实例化channel对象
  • 执行init方法, 再该方法中对option, attr进行初始化, 添加HandleraddLast, 初始化ServerBootstrapAcceptor
  • 执行register(channel)方法进行注册
  • 找到register0方法
  • 具体的注册实现doRegister()
  • 进行通知
  • 判断监听是否启动
  • 如果启动且是首次连接, 则进行回调

over

那么本篇文章就讲完了, 按理来讲回调之后也应该讲一下的, 但是我发现继续写的话, 下一个任务的我也写完了, 本来21篇文章就不好写, 这个地方单独去讲一下也比较合适, 见谅见谅

目录
相关文章
|
2月前
|
Java
【Netty 网络通信】Netty 工作流程分析
【1月更文挑战第9天】Netty 工作流程分析
|
2月前
|
Java Maven
【Netty 网络通信】启动通信服务端
【1月更文挑战第9天】【Netty 网络通信】启动通信服务端
|
2月前
|
Java Unix Linux
【Netty技术专题】「原理分析系列」Netty强大特性之Native transports扩展开发实战
当涉及到网络通信和高性能的Java应用程序时,Netty是一个强大的框架。它提供了许多功能和组件,其中之一是JNI传输。JNI传输是Netty的一个特性,它为特定平台提供了高效的网络传输。 在本文中,我们将深入探讨Netty提供的特定平台的JNI传输功能,分析其优势和适用场景。我们将介绍每个特定平台的JNI传输,并讨论其性能、可靠性和可扩展性。通过了解这些特定平台的JNI传输,您将能够更好地选择和配置适合您应用程序需求的网络传输方式,以实现最佳的性能和可靠性。
90 7
【Netty技术专题】「原理分析系列」Netty强大特性之Native transports扩展开发实战
|
2月前
|
网络协议 Java 物联网
Spring Boot与Netty打造TCP服务端(解决粘包问题)
Spring Boot与Netty打造TCP服务端(解决粘包问题)
188 1
|
8月前
netty的异常分析 IllegalReferenceCountException refCnt: 0, decrement: 1
netty的异常分析 IllegalReferenceCountException refCnt: 0, decrement: 1
94 0
|
2月前
|
安全 Java Go
springboot+netty化身Udp服务端,go化身客户端模拟设备实现指令联动
springboot+netty化身Udp服务端,go化身客户端模拟设备实现指令联动
107 0
|
2月前
|
测试技术
Netty4 websocket 开启服务端并设置IP和端口号
Netty4 websocket 开启服务端并设置IP和端口号
99 0
|
2月前
|
前端开发 Java Maven
【Netty 网络通信】启动客户端连接服务端实现通信
【1月更文挑战第9天】【Netty 网络通信】启动客户端连接服务端实现通信
|
2月前
|
前端开发 网络协议 Java
Netty | 工作流程图分析 & 核心组件说明 & 代码案例实践
Netty | 工作流程图分析 & 核心组件说明 & 代码案例实践
144 0
|
8月前
|
前端开发
Netty4 读写水位控制分析
Netty4 读写水位控制分析
50 0