当前位置: 首页 > news >正文

[Netty源码] 服务端启动过程 (二)

文章目录

      • 1.ServerBootstrap
      • 2.服务端启动过程
      • 3.具体步骤分析
        • 3.1 创建服务端Channel
        • 3.2 初始化服务端Channel
        • 3.3 注册selector
        • 3.4 端口绑定

1.ServerBootstrap

ServerBootstrap引导服务端启动流程:

在这里插入图片描述


//主EventLoopGroup
NioEventLoopGroup master = new NioEventLoopGroup();
//从EventLoopGroup
NioEventLoopGroup worker = new NioEventLoopGroup();
//服务端引导类
ServerBootstrap bootstrap = new ServerBootstrap();
//配置主从EventLoopGroup
bootstrap.group(master, worker);
//channel选项配置
bootstrap.option(ChannelOption.SO_KEEPALIVE, true).option(ChannelOption.CONNECT_TIMEOUT_MILLIS,5000);
bootstrap.channel(NioServerSocketChannel.class);
//主EventLoopGroup ChannelHandler配置
bootstrap.handler(new ChannelInboundHandlerAdapter(){@Overridepublic void channelRegistered(ChannelHandlerContext ctx) throws Exception {System.out.println("Master:" + ctx.channel().eventLoop().toString());super.channelRegistered(ctx);}
});
//从EventLoopGroup ChannelHandler配置
bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {System.out.println("Child:" + ch.eventLoop().toString());}
});
//调用bind方法开始监听端口8888
ChannelFuture future = bootstrap.bind(8888).sync();
future.channel().closeFuture().sync();master.shutdownGracefully().sync();

以上代码使用的是Netty框架中经典的主从事件驱动模式

2.服务端启动过程

  1. main方法调用ServerBootstrap.bind()方法

  2. validate()方法验证必要配置参数

  3. 调用AbstractBootstrap.initAndRegister()方法

  4. 调用channelFactory.newChannel()方法创建Channel实例

  5. ServerBootstrap.init()初始化Channel实例,配置ChannelOption、attributes;在Channel的pipeline中配置默认的ChannelHandler实例

  6. 将Channel实例注册到主EventLoopGroup中并返回ChannelFuture

  7. 注册ChannelFuture回调,在完成后调用channel.bind()方法完成端口监听

3.具体步骤分析

1.创建服务端Channel
2.初始化服务端Channel
3.注册Selector
4.端口绑定

3.1 创建服务端Channel

在这里插入图片描述

AbstractBootstrap.bind()

在这里插入图片描述

  1. validate(): 验证必要配置参数
  2. AbstractBootstrap.doBind()

在这里插入图片描述

AbstractBootstrap.initAndRegister()

在这里插入图片描述

  1. 利用反射创建Channel, 得到NioServerSocketChannel
  2. 初始化channel中的一些参数

在这里插入图片描述

AbstractBootstrap.channel() 反射创建Channel

在这里插入图片描述

利用反射创建channel, 得到ReflectiveChannelFactory, 调用channelFactory利用工厂模式, 最后生成NioServerSocketChannel

在这里插入图片描述

3.2 初始化服务端Channel

ServerBootstrap.init() 初始化一些基本参数

初始化一些Options和Attrs和group和handler的参数

在这里插入图片描述

    @Overridevoid init(Channel channel) throws Exception {final Map<ChannelOption<?>, Object> options = options0();synchronized (options) {setChannelOptions(channel, options, logger);}final Map<AttributeKey<?>, Object> attrs = attrs0();synchronized (attrs) {for (Entry<AttributeKey<?>, Object> e: attrs.entrySet()) {@SuppressWarnings("unchecked")AttributeKey<Object> key = (AttributeKey<Object>) e.getKey();channel.attr(key).set(e.getValue());}}ChannelPipeline p = channel.pipeline();final EventLoopGroup currentChildGroup = childGroup;final ChannelHandler currentChildHandler = childHandler;final Entry<ChannelOption<?>, Object>[] currentChildOptions;final Entry<AttributeKey<?>, Object>[] currentChildAttrs;synchronized (childOptions) {currentChildOptions = childOptions.entrySet().toArray(newOptionArray(0));}synchronized (childAttrs) {currentChildAttrs = childAttrs.entrySet().toArray(newAttrArray(0));}p.addLast(new ChannelInitializer<Channel>() {@Overridepublic void initChannel(final Channel ch) throws Exception {final ChannelPipeline pipeline = ch.pipeline();ChannelHandler handler = config.handler();if (handler != null) {pipeline.addLast(handler);}ch.eventLoop().execute(new Runnable() {@Overridepublic void run() {pipeline.addLast(new ServerBootstrapAcceptor(ch, currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs));}});}});}

在这里插入图片描述

设置 currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs

在这里插入图片描述

在Channel的pipeline中配置默认的ChannelHandler实例

在这里插入图片描述

ServerBootstrapAcceptor 添加连接器, ServerBootstrapAcceptor本质是一个handler

3.3 注册selector

bind -> initAndRegister -> AbstractChannel.register -> this.eventLoop = eventLoop, register0 实际注册 -> doRegister(), invokeHandlerAddedIfNeeded(), fireChannelRegistered() 传播事件

在这里插入图片描述

AbstractChannel.AbstractUnsafe.register()

在这里插入图片描述

register0()

在这里插入图片描述

AbstractNioChannel.doRegister()

在这里插入图片描述

上面有javaChannel.register(), 利用jdk底层去创建selector

3.4 端口绑定

bind() -> doBind() -> doBind0() -> AbstracChannel,bind() -> DefaultChannelPipeline.bind() -> AbstractChannlHandlerContext.bind() -> AbstractChannlHandlerContext.invokeBind() -> DefaultChannelPipeline.HeadContext.bind() -> NioSocketChannel.doBind0(), pipeline.fireChannelActive();

最后将会调用DefaultChannelPipeline.HeadContext.bind(), 因为DefaultChannelPipeline在初始化时会设置pipeline队列的首尾分别为DefaultChannelPipeline.HeadContext与DefaultChannelPipeline.TailContext
bind()在Pipeline中走的是出站方法,是从管道的后面向前走,最后到达管道头部的ChannelHandler(也就是DefaultChannelPipeline.HeadContext),这一过程会调用同一方向上所有ChannelHandler的bind()事件。

AbstractBootstrap.doBind0(): 添加一个任务至EventLoop中, 最后将会调用DefaultChannelPipeline.HeadContext.bind()方法

在这里插入图片描述

AbstractChannlHandlerContext.invokeBind()

在这里插入图片描述

DefaultChannelPipeline.HeadContext.bind() -> AbstractChannel.AbstractUnsafe.bind()

        @Overridepublic final void bind(final SocketAddress localAddress, final ChannelPromise promise) {assertEventLoop();if (!promise.setUncancellable() || !ensureOpen(promise)) {return;}boolean wasActive = isActive();try {doBind(localAddress);} catch (Throwable t) {safeSetFailure(promise, t);closeIfClosed();return;}if (!wasActive && isActive()) {invokeLater(new Runnable() {@Overridepublic void run() {pipeline.fireChannelActive();}});}safeSetSuccess(promise);}
  1. NioSocketChannel.doBind() -> NioSocketChannel.doBind0()
  2. pipeline.fireChannelActive()

通过在pipline中的层层传递, 现在来到了最终执行bind操作的终点, 执行bind方法,

在这里插入图片描述

可以通过SocketUtils.bind() 绑定JDK底层的端口

最后如果触发了一个事件的话, 会调用Channel.read()事件(AbstractNioChannel.doBeginRead()), 这个事件对于服务端来说就是一个新的连接接入。

相关文章:

[Netty源码] 服务端启动过程 (二)

文章目录1.ServerBootstrap2.服务端启动过程3.具体步骤分析3.1 创建服务端Channel3.2 初始化服务端Channel3.3 注册selector3.4 端口绑定1.ServerBootstrap ServerBootstrap引导服务端启动流程: //主EventLoopGroup NioEventLoopGroup master new NioEventLoopGroup(); //从E…...

Week 14

代码源每日一题Div2 106. 订单编号 原题链接&#xff1a;订单编号 思路&#xff1a;这题本来没啥思路&#xff0c;直到获得了某位佬的提示才会做&#xff08; 我们可以用set来维护一些区间&#xff0c;这些区间为 pair 类型&#xff0c;表示没有使用过的编号&#xff0c;每次…...

【微信小程序】-- 使用 Git 管理项目(五十)

&#x1f48c; 所属专栏&#xff1a;【微信小程序开发教程】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &…...

leetcode每日一题:134. 加油站

系列&#xff1a;贪心算法 语言&#xff1a;java 题目来源&#xff1a;Leetcode134. 加油站 题目 在一条环路上有 n 个加油站&#xff0c;其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车&#xff0c;从第 i 个加油站开往第 i1 个加油站需要消耗汽油 cost[…...

开放式基金实时排行 API 数据接口

开放式基金实时排行 API 数据接口 多维度参数返回&#xff0c;实时数据&#xff0c;类型参数筛选。 1. 产品功能 返回实时开放式基金排行数据可定义查询基金类型参数&#xff1b;多个基金属性值返回多维指标&#xff0c;一次查询毫秒级返回&#xff1b;数据持续更新与维护&am…...

Android开发中synchronized的实现原理

synchronized的三种使用方式 **1.修饰实例方法,**作用于当前实例加锁&#xff0c;进入同步代码前要获得当前实例的锁。 没有问题的写法&#xff1a; public class AccountingSync implements Runnable{//共享资源(临界资源)static int i0;/*** synchronized 修饰实例方法*/p…...

【华为OD机试 2023最新 】 统一限载货物数最小值(C++)

题目描述 火车站附近的货物中转站负责将到站货物运往仓库,小明在中转站负责调度2K辆中转车(K辆干货中转车,K辆湿货中转车)。 货物由不同供货商从各地发来,各地的货物是依次进站,然后小明按照卸货顺序依次装货到中转车,一个供货商的货只能装到一辆车上,不能拆装,但是…...

【生活工作经验 十】ChatGPT模型对话初探

最近探索了下全球大火的ChatGPT&#xff0c;想对此做个初步了解 一篇博客 当今社会&#xff0c;自然语言处理技术得到了迅速的发展&#xff0c;人工智能技术也越来越受到关注。其中&#xff0c;基于深度学习的大型语言模型&#xff0c;如GPT&#xff08;Generative Pre-train…...

基于Spring Boot房产销售平台的设计与实现【源码+论文】分享

开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.3.9 摘要 信息技术的发展…...

不同类型的电机的工作原理和控制方法汇总

电机控制是指对电机的启动、调速&#xff08;加速、减速&#xff09;、运转方向和停止进行的控制&#xff0c;不同类型的电机有着不同的工作原理和控制方法。 一、无刷电机 无刷电机是由电机主体和电机驱动板组成的一种没有电刷和换向器的机电一体化产品。在无刷电机中&#xf…...

计算机网络管理 TCP三次握手的建立过程,Wireshark抓包分析并验证TCP三次握手建立连接的报文

⬜⬜⬜ ---&#x1f7e7;&#x1f7e8;&#x1f7e9;&#x1f7e6;&#x1f7ea; (*^▽^*)欢迎光临 &#x1f7e7;&#x1f7e8;&#x1f7e9;&#x1f7e6;&#x1f7ea;---⬜⬜⬜ ✏️write in front✏️ &#x1f4dd;个人主页&#xff1a;陈丹宇jmu &#x1f381;欢迎各位→…...

HTTP/2.x:最新的网页加载技术,快速提高您的SEO排名

2.1 http2概念HTTP/2.0&#xff08;又称HTTP2&#xff09;是HTTP协议的第二个版本。它是对HTTP/1.x的更新&#xff0c;旨在提高网络性能和安全性。HTTP/2.0是由互联网工程任务组&#xff08;IETF&#xff09;标准化的&#xff0c;并于2015年发布。2.2 http2.x与http1.x区别HTTP…...

机器学习----线性回归

第一关&#xff1a;简单线性回归与多元线性回归 1、下面属于多元线性回归的是&#xff1f; A、 求得正方形面积与对角线之间的关系。 B、 建立股票价格与成交量、换手率等因素之间的线性关系。 C、 建立西瓜价格与西瓜大小、西瓜产地、甜度等因素之间的线性关系。 D、 建立西瓜…...

MS2131 USB 3.0 高清音视频采集+HDMI 环出+混音处理芯片 应用网络直播一体机

MS2131 是一款 USB 3.0 高清视频和音频采集处理芯片&#xff0c;内部集成 USB 3.0 Device 控制器、 数据收发模块、音视频处理模块。MS2131 可以通过 USB 3.0 接口将 HDMI 输入的音视频信号传 送到 PC、智能手机、平板电脑上预览或采集。MS2131 支持 HDMI 环出功能&#xff0c;…...

基于堆与AdjustDown的TOP-K问题

TIPSTOP-K问题TOP-K问题&#xff1a;就是说现在比如说有n个数据&#xff0c;然后需要从这n个数据里面找到最大的或最小的前k个。一般来讲思路的话就是&#xff1a;先把这n个数据给他建一个堆&#xff0c;建堆完成之后&#xff0c;然后就去调堆&#xff0c;然后大概只需要调k次&…...

在CentOS上安装Docker引擎

1,先决条件#### 1-1操作系统要求1-2 卸载旧版本 2,安装方法2-1使用存储库安装设置存储库安装 Docker 引擎 本文永久更新地址: 官方地址&#xff1a;https://docs.docker.com/engine/install/centos/ 1,先决条件 #### 1-1操作系统要求 要安装 Docker Engine&#xff0c;您需要…...

【10】核心易中期刊推荐——模式识别与机器学习

🚀🚀🚀NEW!!!核心易中期刊推荐栏目来啦 ~ 📚🍀 核心期刊在国内的应用范围非常广,核心期刊发表论文是国内很多作者晋升的硬性要求,并且在国内属于顶尖论文发表,具有很高的学术价值。在中文核心目录体系中,权威代表有CSSCI、CSCD和北大核心。其中,中文期刊的数…...

【数据结构】并查集

目录 一&#xff1a;用途 二&#xff1a;实现 O(1) 三&#xff1a;例题 例题1&#xff1a;集合 例题2&#xff1a;连通图无向 例题3&#xff1a;acwing 240 食物链 一&#xff1a;用途 将两个集合合并询问两个元素是否在一个集合当中 二&#xff1a;实现 O(1) 每…...

软考--网络攻击分类

网络攻击的主要手段包括口令入侵、放置特洛伊木马程序、拒绝服务&#xff08;DoS)攻击、端口扫描、网络监听、欺骗攻击和电子邮件攻击等。口令入侵是指使用某些合法用户的账号和口令登录到目的主机&#xff0c;然后再实施攻击活动。特洛伊木马&#xff08;Trojans)程序常被伪装…...

蓝桥杯刷题冲刺 | 倒计时17天

作者&#xff1a;指针不指南吗 专栏&#xff1a;蓝桥杯倒计时冲刺 &#x1f43e;马上就要蓝桥杯了&#xff0c;最后的这几天尤为重要&#xff0c;不可懈怠哦&#x1f43e; 文章目录1.长草2.分考场1.长草 题目 链接&#xff1a; 长草 - 蓝桥云课 (lanqiao.cn) 题目描述 小明有一…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来

一、破局&#xff1a;PCB行业的时代之问 在数字经济蓬勃发展的浪潮中&#xff0c;PCB&#xff08;印制电路板&#xff09;作为 “电子产品之母”&#xff0c;其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透&#xff0c;PCB行业面临着前所未有的挑战与机遇。产品迭代…...

Day131 | 灵神 | 回溯算法 | 子集型 子集

Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 笔者写过很多次这道题了&#xff0c;不想写题解了&#xff0c;大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话&#xff1a; “利润不是赚出来的&#xff0c;是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业&#xff0c;很多企业看着销售不错&#xff0c;账上却没钱、利润也不见了&#xff0c;一翻库存才发现&#xff1a; 一堆卖不动的旧货…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

SpringTask-03.入门案例

一.入门案例 启动类&#xff1a; package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

中医有效性探讨

文章目录 西医是如何发展到以生物化学为药理基础的现代医学&#xff1f;传统医学奠基期&#xff08;远古 - 17 世纪&#xff09;近代医学转型期&#xff08;17 世纪 - 19 世纪末&#xff09;​现代医学成熟期&#xff08;20世纪至今&#xff09; 中医的源远流长和一脉相承远古至…...

Linux nano命令的基本使用

参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时&#xff0c;显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...