当前位置: 首页 > 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) 题目描述 小明有一…...

Android Method Tracing深度解析:Unity性能瓶颈跨层归因实战

1. 为什么Method Tracing不是“点一下就出报告”的银弹&#xff0c;而是Android性能诊断的听诊器在Unity项目上线前的最后两周&#xff0c;我接手了一个卡顿严重的AR应用——启动后3秒内帧率从60掉到22&#xff0c;用户滑动模型时UI直接冻结。团队里有人立刻打开Profiler&#…...

《从 0 实现 SGLang》第 1 篇 · LLM 推理引擎到底在做什么

千行代码&#xff0c;一步步搭出一个现代 LLM 推理引擎&#xff0c;吃透大模型推理的每一项关键技术。 本阶段目标 — 最简推理实现 用最朴素的方式把端到端推理跑通&#xff1a;先搭起整体框架&#xff0c;再逐个模块替换为完整实现。整个阶段共 5 篇短文&#xff1a; 序号…...

别再死记公式了!用Python手把手实现粒子群算法(PSO)优化函数寻优

别再死记公式了&#xff01;用Python手把手实现粒子群算法&#xff08;PSO&#xff09;优化函数寻优 粒子群算法&#xff08;PSO&#xff09;作为经典的群体智能优化方法&#xff0c;常被用于解决复杂的非线性优化问题。但大多数教程都停留在数学公式推导层面&#xff0c;让初学…...

Adobe-GenP:创意工作者的智能许可证管理解决方案

Adobe-GenP&#xff1a;创意工作者的智能许可证管理解决方案 【免费下载链接】Adobe-GenP Adobe CC 2019/2020/2021/2022/2023 GenP Universal Patch 3.0 项目地址: https://gitcode.com/gh_mirrors/ad/Adobe-GenP 在数字创意领域&#xff0c;Adobe Creative Cloud系列软…...

Unity哥特UI资源包:SDF字体与Shader Graph工程化实践

1. 为什么哥特UI在游戏开发中长期被低估&#xff0c;又为何现在必须认真对待“哥特UI”这个词&#xff0c;很多Unity开发者第一反应是&#xff1a;不就是黑底、尖角、浮雕字、带玫瑰纹样的按钮吗&#xff1f;配个暗红渐变完事。我2019年接手一个中世纪黑暗奇幻RPG时也这么想——…...

VM振弦采集模块精度实测:从标准信号源到误差分析全流程

1. 项目概述与核心价值最近在做一个岩土工程安全监测的项目&#xff0c;其中有个环节让我琢磨了好一阵子&#xff1a;如何准确地评估我们用的那批VM振弦采集模块的测量精度。这玩意儿在结构健康监测、桥梁隧道、边坡稳定性监测里用得非常多&#xff0c;核心任务就是读取振弦式传…...

3分钟掌握CPU-X:Linux系统硬件信息检测的完整指南

3分钟掌握CPU-X&#xff1a;Linux系统硬件信息检测的完整指南 【免费下载链接】CPU-X CPU-X is a Free software that gathers information on CPU, motherboard and more 项目地址: https://gitcode.com/gh_mirrors/cp/CPU-X 你是否曾经想知道自己的Linux电脑到底用了什…...

人工模仿智能在专业领域中的挣扎

原文&#xff1a;towardsdatascience.com/the-struggle-of-artificially-imitated-intelligence-in-specialist-domains-6e63a4e0ebfc?sourcecollection_archive---------4-----------------------#2024-05-08 为什么通向真正智能的道路要经过本体论和知识图谱 https://mediu…...

GLSL优化器核心优化技术详解:函数内联、死代码消除与常量传播

GLSL优化器核心优化技术详解&#xff1a;函数内联、死代码消除与常量传播 【免费下载链接】glsl-optimizer GLSL optimizer based on Mesas GLSL compiler. Used to be used in Unity for mobile shader optimization. 项目地址: https://gitcode.com/gh_mirrors/gl/glsl-opt…...

双榜第一!文心5.1登顶中文创意写作综合实力评测

【大力财经】5月18日&#xff0c;全球权威ICT领域市场研究机构Omdia发布《2026 年基础模型中文创意写作能力评估》报告&#xff0c;围绕中文创意写作七大核心维度&#xff0c;对 DeepSeek V4、文心5.1&#xff08;ERNIE 5.1&#xff09;、GPT 5.5 等 8大国内外主流顶级文本模型…...