目录
EventloopGroup 了解么? 和 EventLoop 啥关系?
Bootstrap 和 ServerBootstrap 是什么?
NioEventLoopGroup 默认的构造函数会起多少线程?
参考:1.《v4.0-JavaGuide面试突击版》
2.黑马课程
Netty 是什么?
1. Netty 是⼀个 基于 NIO 的 client-server(客户端服务器)框架,使⽤它可以快速简单地开发⽹
络应⽤程序。
2. 它极⼤地简化并优化了 TCP 和 UDP 套接字服务器等⽹络编程,并且性能以及安全性等都更好。
Spring之于javaEE,Netty之于网络通信。
为什么要⽤ Netty?
性能上优于原生的Java API,开发效率高,网络吞吐量大。
很多人都在用,很多项目都在用,可靠。
具体的:
1.统⼀的 API,⽀持多种传输类型,阻塞和⾮阻塞的。
2.简单⽽强⼤的线程模型。
3.⾃带编解码器解决 TCP 粘包/拆包(半包)问题。
4.⾃带各种协议栈。
5.⽐直接使⽤ Java 核⼼ API 有更⾼的吞吐量、更低的延迟、更低的资源消耗和更少的内存复
制。
6.成熟稳定,经历了⼤型项⽬的使⽤和考验,⽽且很多开源项⽬都使⽤到了 Netty, ⽐如我们
经常接触的 Dubbo、RocketMQ 等等。
Netty 应⽤场景有哪些?
作为 RPC 框架的⽹络通信⼯具 (分布式应用会用到)
手写RPC框架(文末附代码)_trigger的博客-CSDN博客
实现⼀个 HTTP 服务器
实现⼀个即时通讯系统
实现消息推送系统
Netty 核⼼组件有哪些?分别有什么作⽤?
比如现在有服务器和客户端,场景是PRC调用。
服务器已经启动,有一个核心组件正在运行,这个组件就是事件循环EventLoop,它不断的监听当前端口是否有请求(连接请求)。
客户端通过channel去bind对应的ip+port,建立连接。
然后客户端就可以发送请求,发送的时候涉及到核心组件pipeline和handler,最简单的,需要将自己的请求通过编码器这个handler编码后传输(handler在pipeline中),编码后的信息来到服务器的channel后,又进入服务器的pipeline,通过解码器这个handler解码,交由EventLoop处理请求,得到结果后再编码返回。
具体的:
1.Channel
Channel 接⼝是 Netty 对⽹络操作抽象类,它除了包括基本的 I/O 操作,如
bind() 、 connect() 、 read() 、 write() 等。
2.EventLoop
EventLoop 的主要作⽤实际就是负责监听⽹络事件并调⽤事件处理器进⾏相关 I/O 操作的处理。
3.Channel的Handler 和Pipeline
Handler 是消息的具体处理器。他负责处理读写操作、客户端连接等事情。
Pipeline 为Handler 的链,提供了⼀个容器并定义了⽤于沿着链传播⼊站和出站
事件流的 API 。当Channel 被创建时,它会被⾃动地分配到它专属的 Pipeline 。
我们可以在 Pipeline 上通过 addLast() ⽅法添加⼀个或者多个 Handler ,因为⼀
个数据或者事件可能会被多个 Handler 处理。当⼀个 Handler 处理完之后就将数据交给
下⼀个 Handler 。
EventloopGroup 了解么? 和 EventLoop 啥关系?
EventloopGroup 是EventLoop 的集合
参见下图
Bootstrap 和 ServerBootstrap 是什么?
Bootstrap 、ServerBootstrap 是客户端和服务器端的启动引导类,通常ServerBootstrap 通常使⽤ bind()⽅法绑定本地的端⼝上,然后等待客户端的连接。
Bootstrap 只需要配置⼀个线程组 EventLoopGroup ,⽽ ServerBootstrap 需要配置两个线
程组EventLoopGroup ,⼀个⽤于接收连接(bossGroup),⼀个⽤于具体的处理(workerGroup)。
Bootstrap和 ServerBootstrap的使用步骤大致包括设置信道,确定线程模型,添加ChannelInitializer ,绑定端口,设置一些参数等。
NioEventLoopGroup 默认的构造函数会起多少线程?
NioEventLoopGroup 默认的构造函数实际会起的线程数为 CPU*2
Netty 线程模型了解么?
设计模式:Reactor 模式
从⼀个 主线程 NIO 线程池中选择⼀个线程作为 Acceptor 线程,绑定监听端⼝,接收客户端连接
的连接,其他线程负责后续的接⼊认证等⼯作。连接建⽴完成后,从属 NIO 线程池负责具体处理
I/O 读写。
BossGroup负责 accept, 连接后交由 WorkerGroup负责读写处理等。
BossGroup监听客户端的连接,WorkerGroup监听读写事件。
什么是 TCP 粘包/半包?有什么解决办法呢?
粘包:好多句子 (包) 拼成了一个段落(流)
半包:一个完整的句子(包)被拆分成了两半(流)
主要是因为TCP当中, 只有流的概念, 没有包的概念。
解决办法:使⽤ Netty ⾃带的解码器
LineBasedFrameDecoder : 发送端发送数据包的时候,每个数据包之间以换⾏符作为分
隔, LineBasedFrameDecoder 的⼯作原理是它依次遍历 ByteBuf 中的可读字节,判断是否
有换⾏符,然后进⾏相应的截取。
DelimiterBasedFrameDecoder : 可以⾃定义分隔符解码器, LineBasedFrameDecoder 实际
上是⼀种特殊的 DelimiterBasedFrameDecoder 解码器。
FixedLengthFrameDecoder : 固定⻓度解码器,它能够按照指定的⻓度对消息进⾏相应的拆
包。
比较常用的是LengthFieldBasedFrameDecoder
LengthFieldBasedFrameDecoder 介绍:
ch.pipeline().addLast(new LengthFieldBasedFrameDecoder(1024, 0, 1, 0, 1));
//自定义协议解码器
/** 入参有5个,分别解释如下maxFrameLength:框架的最大长度。如果帧的长度大于此值,则将抛出TooLongFrameException。
lengthFieldOffset:长度字段的偏移量:即对应的长度字段在整个消息数据中得位置
lengthFieldLength:长度字段的长度。如:长度字段是int型表示,那么这个值就是4(long型就是8)
lengthAdjustment:要添加到长度字段值的补偿值
initialBytesToStrip:从解码帧中去除的第一个字节数
*/
Netty 长连接是什么,应用场景有哪些?
Netty长连接和http长连接都是基于TCP长连接 的。
长连接和短连接的区别:
长连接相较于短连接,节约时间和网络资源。
TCP 在进⾏读写之前,server 与 client 之间必须提前建⽴⼀个连接。建⽴连接的过程,需要三次握⼿,释放/关闭连接的话需要四次挥⼿。这个过程是比较消耗⽹络资源并且有时间延迟的。
短连接说的就是 server 端 与 client 端建⽴连接之后,读写完成之后就关闭掉连接,如果
下⼀次再要互相发送消息,就要重新连接。短连接的优点很明显,就是管理和实现都比较简单,
缺点也很明显,每⼀次的读写都要建⽴连接必然会带来⼤量⽹络资源的消耗,并且连接的建⽴也
需要耗费时间。
长连接说的就是 client 向 server 双⽅建⽴连接之后,即使 client 与 server 完成⼀次读写,它们
之间的连接并不会主动关闭,后续的读写操作会继续使⽤这个连接。⻓连接的可以省去较多的
TCP 建⽴和关闭的操作,降低对⽹络资源的依赖,节约时间。对于频繁请求资源的客户来说,⾮
常适⽤⻓连接。
长连接的操作步骤是:
建立连接->数据传输…(保持连接)…数据传输->关闭连接。
建立连接->数据传输->关闭连接…建立连接->数据传输->关闭连接。
TCP长/短连接的应用场景 转载:
TCP长连接和短链接的区别及应用场景_haikuotiankongdong的博客-CSDN博客_tcp长连接和短连接的区别
1、长连接多用于操作频繁,点对点的通讯,而且连接数不能太多情况。每个TCP连接都需要三次握手,这需要时间,如果每个操作都是先连接,再操作的话那么处理速度会降低很多,所以每个操作完后都不断开,再次处理时直接发送数据包就OK了,不用建立TCP连接。例如:数据库的连接用长连接,如果用短连接频繁的通信会造成socket错误,而且频繁的socket 创建也是对资源的浪费。
2、而像WEB网站的http服务一般都用短连接,因为长连接对于服务端来说会耗费一定的资源,而像WEB网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源,如果用长连接,而且同时有成千上万的用户,如果每个用户都占用一个连接的话,那可想而知吧。所以并发量大,但每个用户无需频繁操作情况下需用短连接好。
总结:
长连接多用于操作频繁,点对点的通讯,而且连接数不能太多情况。 例子: 数据库
短连接多用于并发量大,但每个用户无需频繁操作情况。 例子:WEB网站的http服务
Netty心跳机制了解么?
在 TCP 保持⻓连接的过程中,可能会出现断⽹等⽹络异常出现,异常发⽣的时候, client 与
server 之间如果没有交互的话,它们是⽆法发现对⽅已经掉线的。为了解决这个问题, 我们就需
要引⼊ ⼼跳机制 。
⼼跳机制的⼯作原理是: 在 client 与 server 之间在⼀定时间内没有数据交互时, 即处于 idle 状态
时, 客户端或服务器就会发送⼀个特殊的数据包给对⽅, 当接收⽅收到这个数据报⽂后, 也⽴即发
送⼀个特殊的数据报⽂, 回应发送⽅, 此即⼀个 PING-PONG 交互。所以, 当某⼀端收到⼼跳消息
后, 就知道了对⽅仍然在线, 这就确保 TCP 连接的有效性。
简单的心跳机制实现:
服务器监听信道,如果5s内没有客户端发过来的包,就认为客户端挂掉了,释放该信道。
客户端和服务器建立连接后,在空闲时间(没有读写请求)每隔4s向服务器发送一个数据包,证明自己还“活着”。
Netty 的零拷贝是什么,有什么用?
传统的拷贝
-
用户态与内核态的切换发生了 3 次,这个操作比较重量级
-
数据拷贝了共 4 次
零拷贝
零拷贝指的不是不拷贝 而是减少拷贝的次数
-
java 调用 transferTo 方法后,要从 java 程序的用户态切换至内核态,使用 DMA将数据读入内核缓冲区,不会使用 cpu
-
只会将一些 offset 和 length 信息拷入 socket 缓冲区,几乎无消耗
-
使用 DMA 将 内核缓冲区的数据写入网卡,不会使用 cpu
整个过程仅只发生了一次用户态与内核态的切换,数据拷贝了 2 次。所谓的【零拷贝】,并不是真正无拷贝,而是不会拷贝重复数据到 jvm 内存中。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/92877.html