一.启动概述

了解整体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. R 语言常用操作与函数汇总

    总结了一下 R 语言中常用的一些操作与函数使用,抛砖引玉,分享一下给大家,如有错误的地方欢迎留言指正. 怎样显示 R 软件中某个包中包含的全部数据集? > library(MASS)> d ...

  2. 驱动开发:内核RIP劫持实现DLL注入

    本章将探索内核级DLL模块注入实现原理,DLL模块注入在应用层中通常会使用CreateRemoteThread直接开启远程线程执行即可,驱动级别的注入有多种实现原理,而其中最简单的一种实现方式则是通过 ...

  3. Gazebo、Rviz 结合 ORB-SLAM3 实现运动规划及定位

    博客地址:https://www.cnblogs.com/zylyehuo/ 基于以下内容,详见博客链接 基于机器人自主移动实现SLAM建图 - zylyehuo - 博客园 (cnblogs.com ...

  4. 通过模仿学会Python爬虫(一):零基础上手

    好家伙,爬虫来了 爬虫,这玩意,不会怎么办, 诶,先抄一份作业回来 1.别人的爬虫  Python爬虫史上超详细讲解(零基础入门,老年人都看的懂)_ChenBinBini的博客-CSDN博客 # -* ...

  5. 300行代码模拟cdn

    这一生听过许多道理,但还是过不好这一生,这是因为缺少真正的动手实践,光听道理,缺少动手实践的过程,学习难免会让人觉得味同嚼蜡,所以我的分享都比较倾向于实践,在一次次动手实践的过程中感受知识原本纯真的模 ...

  6. Tab切换以及倒计时组件封装

    1.Tab组件 功能 支持默认选中tab 子元素可以是文本或者图片 自定义tab的数量,并自适应展示 实现方式 用ul > li标签遍历传入的tabs数组参数渲染 判断是否传入背景,未传则显示文 ...

  7. 05-面试必会-SpringBoot&SpringCloud

    01- 讲一讲 SpringBoot 自动装配的原理 1.在 SpringBoot 项目的启动引导类上都有一个注解@SpringBootApplication 这个注解是一个复合注解, 其中有三个注解 ...

  8. Python爬虫突破验证码技巧 - 2Captcha

    在互联网世界中,验证码作为一种防止机器人访问的工具,是爬虫最常遇到的阻碍.验证码的类型众多,从简单的数字.字母验证码,到复杂的图像识别验证码,再到更为高级的交互式验证码,每一种都有其独特的识别方法和应 ...

  9. Centos7中Jar快速启动脚本

    Centos7中Jar快速启动脚本 创建一个文本,将以下脚本内容复制到文本当中,重命名文本后缀为.sh 注意:根据自己的项目进行更改相关内容,对应注释已说明 #!/bin/sh APP_NAME=ma ...

  10. Cilium 系列-2-Cilium 快速安装

    系列文章 Cilium 系列文章 前言 在本章中,我们将直接将 Cilium 安装到 Kubernetes 集群中. 在实验中,我们用到的组件及版本为: Cilium 1.13.4 K3s v1.26 ...