Java NIO 图解 Netty 服务端启动的过程

java,nio,图解,netty,服务端,启动,过程 · 浏览次数 : 136

小编点评

## Netty 服务端启动步骤详解 **1. 启动概述** * Netty 是一个 Java 编程框架,用于构建高性能的 TCP 服务器和客户端。 * 服务器端启动过程包含以下关键步骤: * 创建 channelFactory,用于创建 channel。 * 创建 NioServerSocketChannel,用于创建服务器端通道。 * 设置 channel 的属性,例如端口号、线程数等。 * 绑定 channel 到 selector 上。 * 注册读事件。 **2. 启动步骤详细** **2.1 创建channelFactory** * 通过反射,调用 Class 的 `channelFactory` 属性获取 channelFactory 实例。 * 图中直接使用 `channelFactory` 创建了 `NioServerSocketChannel`。 **2.2.2 NioServerSocketChannel默认构造函数** * `NioServerSocketChannel` 的构造函数调用类的 `initAndRegister` 方法来初始化和注册 channel。 * 其中,`initAndRegister` 方法调用 `configureBlocking` 方法设置 channel 为非阻塞模式。 **2.3 selector 注册** * `NioServerSocketChannel` 在 `register` 方法中注册了 `channel` 到 selector 上。 * `channel` 是 `NioServerSocketChannel` 的通道对象。 **2.4 端口绑定** * `NioServerSocketChannel` 使用 `doBeginRead` 方法激活 `channel` 并向 selector 注册 read 事件。 **3. 总结** * 服务器端启动过程由 `NioServerSocketChannel` 的 `channelFactory` 创建、`NioServerSocketChannel` 创建、设置属性、注册 channel 到 selector 和端口绑定完成。 * 整个过程由 `NioServerSocketChannel` 的构造函数、`initAndRegister` 方法、selector 和 channel 的绑定实现。 **一些问题解答** * **第一问:如何设置channelFactory的路径?** `channelFactory` 在图中从 `channelFactory` 属性中获取。 * **第二问:如何注册selector?** selector 在 `initAndRegister` 方法中创建并注册。 * **第三问:如何绑定端口?** `NioServerSocketChannel` 使用 `doBeginRead` 方法激活 `channel` 并向 selector 注册 read 事件。

正文

一.启动概述

了解整体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 服务端启动的过程相似的内容:

Java NIO 图解 Netty 服务端启动的过程

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

Tars-Java网络编程源码分析

本文从java NIO网络编程的基础知识讲到了Tars框架使用NIO进行网络编程的源码分析。

Netty(1)——NIO基础

本篇主要介绍Java NIO的基本原理和主要组件 Netty是由JBOSS提供的Java开源网络应用程序框架,其底层是基于Java提供的NIO能力实现的。因此为了掌握Netty的底层原理,需要首先了解Java NIO的原理。 NIO简介 计算机主要由CPU、内存、外存、IO设备等硬件组成,计算机执行

Jenkins Pipeline 多分支流水线 Input length = 1

Jenkins 多分支流水线 构建过程中报错。 [Pipeline] // node [Pipeline] End of Pipeline java.nio.charset.MalformedInputException: Input length = 1 at java.base/java.nio

Spring Reactor基本介绍和案例

1. Reactor 对比 1.1 Reactor 线程模型 Reactor 线程模型就是通过 单个线程 使用 Java NIO 包中的 Selector 的 select()方法,进行监听。当获取到事件(如 accept、read 等)后,就会分配(dispatch)事件进行相应的事件处理(han

【转帖】47.直接内存

目录 1.直接内存概述2.`IO`与`NIO`对比3.直接内存的`OOM`与内存大小设置 1.直接内存概述 1.直接内存不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域。 2.直接内存是在Java堆外,直接向系统申请的内存空间 3.Java的NIO库允许使用直接内存,用于数据

今天我们来聊Java IO模型,BIO、NIO、AIO三种常见IO模型

一、写在开头 很久没更新喽,最近build哥一直在忙着工作,忙着写小说,都忘记学习自己的本职了,哈哈,不过现在正式回归! 我们继续学习Java的IO相关内容,之前我们了解到,所谓的IO(Input/Output)就是计算机系统与外部设备之间通信的过程。 二、IO调用过程 接下来我们从应用调用的过程中

Netty-BIO、NIO、AIO、零拷贝-2

Java BIO 编程 一、I/O 模型 1、I/O 模型简单的理解:就是用什么样的通道进行数据的发送和接收,很大程度上决定了程序通信的性能 2、Java 共支持 3 种网络编程模型/IO 模式:BIO、NIO、AIO 3、Java BIO : 同步并阻塞(传统阻塞型),服务器实现模式为一个连接一个

阿里面试:NIO为什么会导致CPU100%?

在 Java 中总共有三种 IO 类型:BIO(Blocking I/O,阻塞I/O)、NIO(Non-blocking I/O,非阻塞I/O)和 AIO(Asynchronous I/O,异步I/O),它们的区别如下: 在 JDK 1.4 之前,只有 BIO 一种模式,其开发过程相对简单,新来一个

JAVA中三种I/O框架——BIO、NIO、AIO

一、BIO(Blocking I/O) BIO,同步阻塞IO模型,应用程序发起系统调用后会一直等待数据的请求,直至内核从磁盘获取到数据并拷贝到用户空间; 在一般的场景中,多线程模型下的BIO是成本较低、收益较高的方式。但是,如果在高并发的场景下,过多的创建线程,会严重占据系统资源,降低系统对外界响应