[Netty] 面试问题 1 (十八)

news/2024/2/21 3:15:05

文章目录

      • 1.Netty的特点
      • 2.Netty应用场景
      • 3. Netty核心组件
      • 4.Netty的线程模型
      • 5. EventloopGroup和EventLoop
      • 6.Netty 的零拷贝
      • 7.Netty 长连接和心跳机制
      • 8.Netty 服务端和客户端的启动过程
      • 9.Netty 的 Channel 和 EventLoop
      • 10.Netty 的 ChannelPipeline
      • 11.Netty 中的 ByteBuf
      • 12.Netty 高性能表现
      • 13.Netty 和 Tomcat 的区别
      • 14.I/O模型
      • 15.TCP 粘包/拆包的原因及解决方法
      • 16.序列化协议

1.Netty的特点

在这里插入图片描述

Netty是一个高性能, 异步事件驱动的网络编程框架, 基于Nio, 提供了简单易用的Api, 用于构建各种类型的网络应用程序。

高性能: Netty使用异步I/O, 非阻塞处理方式, 可处理大量并发连接, 提高系统性能。
易于使用: Netty提供了高度抽象的Api, 可以快速构建各种类型的网络应用程序, web服务, 消息推送, 实时游戏
灵活可扩展: Netty提供了许多可插拔的组件, 可以自由组合。

2.Netty应用场景

在这里插入图片描述

服务器间高性能通信: RPC, HTTP, WebSocket协议的实现
分布式系统的消息传输: Kafka等MQ
游戏服务器: 支持高并发的游戏服务端开发
实时流数据的处理: 音频处理, 实时数据传输

阿里分布式服务框架 Dubbo, RocketMQ使用 Netty 作为通讯的基础

3. Netty核心组件

在这里插入图片描述

4.Netty的线程模型

Netty的线程模型是基于事件驱动的Reactor模型, 它使用少量的线程来处理大量的连接和数据传输, 以提高性能和吞吐量。

在Netty中, 每个连接都分配了一个单独的EventLoop线程, 该线程负责处理所有与该连接相关的事件, 包括数据传输、握手和关闭等。

多个连接可以共享同一个EventLoop线程, 从而减少线程的创建和销毁开销,提高资源利用率。

Netty提供了一些线程模型和线程池配置选项, 可以使用不同的EventLoopGroup实现不同的线程模型, 如单线程模型、多线程模型和主从线程模型等。

还可以设置不同的线程池参数, 如线程数、任务队列大小、线程优先级等, 以调整线程池的工作负载和性能表现。

还可以通过优化网络协议、数据结构、业务逻辑等方面来提高Netty的性能。例如可以使用零拷贝技术避免数据拷贝, 使用内存池减少内存分配和回收的开销, 避免使用阻塞IO和同步操作。

5. EventloopGroup和EventLoop

EventLoopGroup和EventLoop是 Netty 中两个重要的组件。EventLoopGroup 表示一组EventLoop, 它们共同负责处理客户端连接的I/O 事件。

EventLoop 是 Netty 中的一个核心组件, 代表不断循环的 I/O 线程。负责处理一个或多个 Channel 的 I/O 操作, 比如数据的读取, 写入和状态的更改。一个EventLoop可以处理多个 Channel, 一个Channel只会被一个 EventLoop 所处理。

一个应用程序通常会创建两个 EventLoopGroup, 一个用于处理客户端连接, 一个用于处理服务端连接, 当客户端连接到服务器时, 服务端的EventLoopGroup 会将连接分配给一个EventLoop 处理, 以保证所有IO操作得到及时的处理。

6.Netty 的零拷贝

Netty 通过使用 Direct Memory 和 FileChannel 的方式实现零拷贝。

当应用程序将数据写入 Channel 时, Netty 会将数据直接写入到内存缓冲区中, 然后通过操作系统提供的 sendfile 或者 writev 等零拷贝技术, 将数据从内存缓冲区中传输到网络中, 避免中间的多次拷贝操作。当应用程序从 Channel 中读取数据时, Netty 也会将数据直接读取到内存缓冲区中, 然后通过零拷贝技术将数据从内存缓冲区传输到用户空间。

通过零拷贝技术, Netty 可以避免在数据传输过程中对数据进行多次的拷贝操作, 提高了数据传输的效率。

7.Netty 长连接和心跳机制

长连接可以避免频繁建立和关闭连接的开销, Netty 提供了一种长连接的实现方式, Channel的keepalive选项保持连接的状态, 启动Keepalive选项后, 客户端和服务器之间的连接将会自动保持一段时间, 如果在这段时间内没有数据交换, 关闭连接。

Netty 还提供了一种心跳机制来保持连接的状态, 心跳机制可以通过定期向对方发送心跳消息去检测连接是否正常。Netty 提供了一个 IdleStateHandler 类, 实现心态机制, IdleStateHandler 可以设置多个超时时间, 当连接空闲时间超过设定的时间时, 触发事件, 在事件处理方法中进行相应的处理, 比如发送心跳消息。

通过使用长连接和心跳机制, 保证客户端与服务器之间的连接处于正常的状态, 提高了数据传输的效率和性能。

8.Netty 服务端和客户端的启动过程

在这里插入图片描述

  1. 创建 EventLoopGroup 对象, 用于管理和调度事件的处理。通过 EventLoopGroup 创建多个 EventLoop, 并将每个 EventLoop 与一个线程绑定。服务端, 一般会创建两个 EventLoopGroup 对象, 用于接收客户端的连接请求和处理客户端的数据。
  2. 创建 ServerBootstrap 或 Bootstrap 对象。ServerBootstrap 和 Bootstrap 是 Netty 提供的服务端和客户端启动器, 它们封装了启动过程中的各种参数和配置, 在创建 ServerBootstrap 或 Bootstrap 对象时, 需要指定相应的 EventLoopGroup 对象, 并进行一些基本的配置, 比如传输协议、端口号、处理器。
  3. 配置Channel的参数, 比如传输协议、缓冲区大小、心跳检测等。
  4. 绑定 ChannelHandler, ChannelHandler 是用于处理事件的组件, 它可以处理客户端的连接请求、接收客户端的数据、发送数据给客户端等。需要将 ChannelHandler 绑定到相应的 Channel 上。
  5. 启动服务端或客户端, 进行一些基本的初始化, 比如注册监听器, 绑定端口。

9.Netty 的 Channel 和 EventLoop

Channel代表一个开放的网络连接, 可以用来读取和写入数据, EventLoop则代表一个执行任务的线程, 负责处理Channel上所有的事件和操作。

每个Channel都与一个EventLoop关联, 而一个EventLoop可以关联多个Channel。当一个Channel 有事件发生时, 比如数据读写, 会将事件提交给关联的EventLoop 处理。EventLoop会将该事件加入到它自己的任务队列中, 顺序处理队列的任务。

一个EventLoop实例可能会被多个Channel所共享, 因此它需要能够处理多个Channel上的事件, 并确保在处理每个Channel的事件时不会被阻塞。为此, Netty 采用了事件循环模型, 通过异步IO和事件驱动方式, 实现了高效, 可扩展的网络编程。

10.Netty 的 ChannelPipeline

Netty中, 每个Channel都有一个与之关联的ChannelPipeline, 用于处理该Channel上的事件和请求。ChannelPipeline是一种基于事件驱动的处理机制, 它由多个处理器(Handler)组成, 每个处理器负责处理一个或多个事件类型, 将事件转换为下一个处理器所需的数据格式。

当一个事件被触发时, 从第一个处理器 InboundHandler 开始流经所有的处理器, 直到到达最后一个处理器或者被中途拦截, 通过抛出异常或调用ChannelHandlerContext.fireXXX()方法实现。

  1. 入站(Inbound)事件:由Channel接收到的事件,例如读取到新的数据、连接建立完成等等。入站事件将从ChannelPipeline的第一个InboundHandler开始流动,直到最后一个InboundHandler。
  2. 出站(Outbound)事件:由Channel发送出去的事件,例如向对端发送数据、关闭连接等等。出站事件将从ChannelPipeline的最后一个OutboundHandler开始流动,直到第一个OutboundHandler。
  3. ChannelHandlerContext:表示处理器和ChannelPipeline之间的关联关系。每个ChannelHandler都有一个ChannelHandlerContext,通过该对象可以实现在ChannelPipeline中的事件流中向前或向后传递事件,也可以通过该对象访问Channel、ChannelPipeline和其他ChannelHandler等。

通过使用ChannelPipeline,Netty实现了高度可配置和可扩展的网络通信模型,使得开发人员可以根据自己的需求选择和组合不同的处理器,以构建出高效、稳定、安全的网络通信系统。

11.Netty 中的 ByteBuf

Netty 的 ByteBuf 是一个可扩展的字节容器

在这里插入图片描述
容量可扩展:ByteBuf的容量可以动态扩展,而 ByteBuffer 的容量是固定的。
内存分配:ByteBuf 内部采用了内存池的方式,可以有效地减少内存分配和释放的开销。
读写操作:ByteBuf 提供了多个读写指针,可以方便地读写字节数据。
零拷贝:ByteBuf 支持零拷贝技术,可以减少数据复制的次数。

12.Netty 高性能表现

  • IO 线程模型: 通过多线程Reactor反应器模式, 在应用层实现异步非阻塞(异步事件驱动)架构, 用最少的资源做更多的事。
  • 内存零拷贝: 尽量减少不必要的内存拷贝, 实现了高效的传输。
  • 内存池设计: 申请的内存可以重用, 指的是直接内存, PooledByteBufAllocator
  • 对象池设计: Recycler, Java对象可以重用, 指Minior GC非常频繁的对象, 如ByteBuffer。对象池使用无锁架构, 和FastThreadLocal
  • mpsc无锁编程: 串形化处理读写, 避免使用锁带来的性能开销。
  • 高性能序列化协议: 支持 protobuf 等高性能序列化协议。

13.Netty 和 Tomcat 的区别

  1. 作用不同: Tomcat 是 Servlet 容器, 可以作为web 服务器, 而Netty 是异步事件驱动的网络应用程序框架和工具用于简化网络编程, 例如TCP和UDP套接字服务器。
  2. 协议不同: Tomcat 是基于 http 协议的 Web 服务器, 而 Netty 能通过编程自定义各种协议, 因为 Netty 本身自己能编码/解码字节流, 所有 Netty 可以实现: HTTP 服务器、FTP 服务器、UDP 服务器、RPC 服务器、WebSocket 服务器、Redis 的 Proxy 服务器、MySQL 的 Proxy 服务器等等。

14.I/O模型

  1. 阻塞I/O: 传统阻塞型I/O(BIO)
    在这里插入图片描述

  2. I/O复用模型
    在这里插入图片描述

  3. Netty的非阻塞I/O的实现关键是基于I/O复用模型
    在这里插入图片描述

15.TCP 粘包/拆包的原因及解决方法

TCP是以流的方式来处理数据

在这里插入图片描述

应用层协议, 比如HTTP协议、DNS协议、FTP协议、POP3协议等。
传输层包含两个协议, TCP和UDP, 指定端口号。
网络层包括ARP协议、IP协议、ICMP协议、IGMP协议等等。
以太网, 每个以太网帧最小64字节, 最大为1500字节。

16.序列化协议

序列化(编码)是将对象序列化为二进制形式(字节数组), 主要用于网络传输、数据持久化等, 而反序列化(解码)则是将从网络、磁盘等读取的字节数组还原成原始对象, 主要用于网络传输对象的解码, 以便完成远程调用。

影响序列化性能的因素: 序列化后的码流大小(网络带宽的占用)、序列化的性能(CPU资源占用)、是否支持跨语言(异构系统的对接和开发语言切换)。

Java默认提供的序列化, 无法跨语言, 序列化后的码流比较大, 序列化性能差

  1. XML: 序列化数据只包含数据本身以及类的结构, 不包括公共属性和字段, 不可以序列化方法, 文件大, 格式复杂, 传输占带宽。
  2. JSON: 是一种轻量级的数据交换格式。
  3. FastJson: 采用一种“假定有序快速匹配”的算法。
  4. Thrift: 不仅是序列化协议, 还是RPC框架。
  5. Avro: Hadoop的一个子项目, 解决了JSON的冗长和没有IDL的问题。
  6. ProtoBuf: 将数据结构以.proto文件进行描述, 通过代码生成工具可以生成对应数据结构的POJO对象和Protobuf相关的方法和属性。
    序列化后码流小, 性能高, 结构化数据存储格式 XML JSON, 通过标识字段的顺序, 实现协议的向前兼容, 结构化的文档更容易管理和维护。
  7. ProtoStuff: 基于protobuf协议, 不需要配置proto文件, 直接导包即可。
  8. Jboss marshaling: 可以直接序列化java类, 无需实现java.io.Serializable接口
  9. Message pack: 一个高效的二进制序列化格式
  10. Hessian: 采用二进制协议的轻量级remoting onhttp工具
  11. Kryo: 基于protobuf协议, 只支持java语言, 需要注册(Registration)然后序列化和反序列化。

http://www.ppmy.cn/news/66734.html

相关文章

第一章 数组

目录 一、二分查找1.1 二分查找母题1.2 搜索插入位置1.3 在排序数组中查找元素的第一个和最后一个位置1.4 x 的平方根1.5 有效的完全平方数 二、双指针2.1 移除元素2.2 删除有序数组中的重复项2.3 移动零2.4 比较含退格的字符串2.5 有序数组的平方 三、滑动窗口3.1 长度最小的子…

HADOOP入门

1.Hadoop简介 组件 Hadoop由4部分组成 1)HDFS:(Hadoop Distribute File System)分布式文件系统,海量数据存储解决方案 2)MapReduce:Hadoop的分布式运算编程框架 3)Yarn:分布式资源调度平台和任务监控平台 4)Commons: HADOOP底层技术支持 主要用来解决:大数据存储,大数据分…

docker入门和docker应用场景,镜像制作,服务编排,docker私服

一、简介 docker解决了什么问题docker和虚拟机的区别在CentOS7里安装docker 1. docker简介 我们写的代码会接触到好几个环境:开发环境、测试环境以及生产环境等等。多种环境去部署同一份代码,由于环境原因往往会出现软件跨环境迁移的问题(也就…

DB2_sql_问题

db2新增字段指定顺序 这个是不能做到的,除非把表删除重新创建的! 原理是这样子的:当你创建表时系统会记录下你的SEQ-ID,就是字段的顺序号,这个是根据字段先后顺序来生成的,系统默认显示的时候也是根据这个来的&#x…

设计模式 - 工厂

文章参考来源 一、概念 创建简单的对象直接 new 一个就完事,但对于创建时需要各种配置的复杂对象例如手机,没有工厂的情况下,用户需要自己处理屏幕、摄像头、处理器等配置,这样用户和手机就耦合在一起了。 可以使代码结构清晰&a…

Unity物理系统脚本编程(下)

一、修改物理材质 Unity对物体表面材料的性质做了件化处理,仅有5种常用属性: Dynamic Friction(动态摩擦系数)Static Friction(静态摩擦系数)Bounciness(弹性系数)Friction Combine…

ES6函数中参数的默认值和解构赋值

ES6函数中参数的默认值 ●给函数的形参设置一个默认值, 当你没有传递实参的时候, 使用默认值 ●直接使用 赋值符号() 给形参赋值即可 function fn(a, b 100) {console.log(a, b)}fn()fn(10)fn(10, 20)复制代码 ES6的函数默认值 ●在ES5之前是没有函数默认值的。函数的默认值是…

金字塔特征融合

金字塔的三种主要结构 FPN: Feature Pyramid Networks for Object Detection (CVPR 2017) PANet: Path Aggregation Network for Instance Segmentation (CVPR 2018) BiFPN: EfficientDet: Scalable and Efficient Object Detection (CVPR 2020) Deep High-Resolution Repre…

软件测试报告模板

目录 2 1 概述... 3 1.1 测试目的... 3 1.2 测试策略... 3 1.3 测试方法... 3 1.4 计划验收标准... 3 1.5 测试用例... 4

上海亚商投顾:沪指缩量调整跌超1% 新能源车产业链掀涨停潮

上海亚商投顾前言:无惧大盘涨跌,解密龙虎榜资金,跟踪一线游资和机构资金动向,识别短期热点和强势个股。 市场情绪 大小指数今日再度分化,沪指低开低走,午后一度跌超1.5%,创业板指则拉升涨超1%&a…

async和await

async 介绍 函数的返回值为promise对象 promise对象的结果由async函数执行的返回值决定 async 函数返回的是一个 Promise 对象。从文档中也可以得到这个信息。async 函数(包含函数语句、函数表达式、Lambda表达式)会返回一个 Promise 对象&#xff0…

一起来!白嫖Amazon DynamoDB!!!

Amazon DynamoDB简介 Amazon DynamoDB是由Amazon Web Services(AWS)提供的一种快速、灵活、全托管的NoSQL数据库服务,支持文档和键/值数据模型。它具有自动扩展、低延迟、高可靠性、高吞吐量等特点,能够处理从几个字节到几TB的数…

闪耀的钥匙:PHP 与访问修饰符

文章目录 参考描述访问修饰符访问修饰符PHP 与访问修饰符publicprotectedprivate 继承中的重写规则可见性举个栗子未重写父类的受保护成员前将受保护成员重写为公有成员将受保护成员重写为私有成员 为什么不允许子类成员设置比父类成员更严格的访问限制? final 关键…

【译】Java 内存泄露的构造和检测

1. 概述 在 Java 应用程序中,内存泄漏会导致严重的性能下降和系统故障。开发人员必须了解内存泄漏的发生原因以及如何识别和解决它们。 在本教程中,我们将提供一个使用失效的监听器问题作为示例来创建 Java 内存泄漏的指南。我们还将讨论各种检测内存泄…

简单随机微分方程数值解

1.随机微分方程求解:dX(t) − αXtdt σdWt 法一:Euler-Maruyama %% %O-U过程 %dX(t)-alpha*Xt*dtsigma*dWt,X|t0X0 %alpha2,sigma1,X01 % 设置初始参数 T 1; % 时间区间长度 N 1000; % 离散化的时间步数 dt T/N; …

linux device tree 中断属性

/* * 设备树的中断属性 */ interrupt-controller /* 中断控制器 */ #interrupt-cells /* 表明引用这个中断控制器的话需要多少个 cell */ #interrupt-cells<1> /* 其它节点要使用这个中断控制器时&#xff0c;只需要一个 cell 来表明使用&quo…

【C语言】扫雷游戏

这里写目录标题 前言1.初始化棋盘2.展示棋盘3.布置雷4.开始扫雷4.1判断输赢4.2扫雷时连续性展开4.3展示玩法 5.整体代码展示5.1 game.h头文件展示5.2 game.c源文件展示5.3 text.c源文件展示 所属专栏&#xff1a;C语言 博主首页&#xff1a;初阳785 代码托管&#xff1a;chuyan…

Java14-常用类:字符串,日期类,比较器

一&#xff1a;字符串&#xff1a;String 1.概述&#xff1a; String&#xff1a;字符串&#xff0c;使用一对""引起来表示。 1.String 声明 为final的&#xff0c;不可被继承 2.String 实现了Serializable接口&#xff1a;表示字符串是支持序列化的。 实现了Co…

Linux系统结构

UNIX/Linux 系统可以粗糙地抽象为 3 个层次&#xff0c;底层是系统内核&#xff08;Kernel&#xff09;&#xff1b;中间层是Shell层&#xff0c;即命令解释层&#xff1b;高层则是应用层。 &#xff08;1&#xff09;内核层 内核层是 UNIX/Linux 系统的核心和基础&#xff0c…

ChatGPT入门到高级【第六章】

第一章&#xff1a;Chatgpt的起源和发展 1.1 人工智能和Chatbot的概念 1.2 Chatbot的历史发展 1.3 机器学习技术在Chatbot中的应用 1.4 Chatgpt的诞生和发展 第二章&#xff1a;Chatgpt的技术原理 2.1 自然语言处理技术 2.2 深度学习技术 2.3 Transformer模型 2.4 GPT模型 第…
最新文章