RPC-常见的Netty面试题
1、Netty是什么?
Netty
成功地找到了一种在不妥协可维护性和性能的情况下实现易于开发,性能,稳定性和灵活性的方法。
Netty
是一个 基于NIO
的client-server
(客户端服务器)框架,使用它可以快速简单地开发网络应用程序;- 它极大地简化并优化了
TCP
和UDP
套接字服务器等网络编程,并且性能以及安全性等很多方面甚至都要更好; Netty
在保证快速和易用性的同时,并没有丧失可维护性和性能等优势。- 支持多种协议 如
FTP
,SMTP
,HTTP
以及各种二进制和基于文本的传统协议。
2、Netty的特点是什么?
- 高并发:
Netty
是一款基于NIO
(Nonblocking IO
,非阻塞IO
)开发的网络通信框架,对比于BIO
(Blocking I/O
,阻塞IO
),他的并发性能得到了很大提高; - 传输快:
Netty
的传输依赖于零拷贝特性,尽量减少不必要的内存拷贝,实现了更高效率的传输; - 封装好:
Netty
封装了NIO
操作的很多细节,提供了易于使用调用接口。
3、什么是 Netty 的零拷贝?
Netty
的接收和发送ByteBuffer
采用DIRECT BUFFERS
,使用堆外直接内存进行Socket
读写,不需要进行字节缓冲区的二次拷贝。如果使用传统的堆内存(HEAP BUFFERS
)进行Socket
读写,JVM
会将堆内存Buffer
拷贝一份到直接内存中,然后才写入Socket
中。相比于堆外直接内存,消息在发送过程中多了一次缓冲区的内存拷贝;Netty
提供了组合Buffer
对象,可以聚合多个ByteBuffer
对象,用户可以像操作一个Buffer
那样方便的对组合Buffer
进行操作,避免了传统通过内存拷贝的方式将几个小Buffer
合并成一个大的Buffer
;Netty
的文件传输采用了transferTo
方法,它可以直接将文件缓冲区的数据发送到目标Channel
,避免了传统通过循环write
方式导致的内存拷贝问题。
4、为什么要使用Netty?
- 使用简单:封装了
NIO
的很多细节,使用更简单; - 功能强大:预置了多种编解码功能,支持多种主流协议。
- 定制能力强:可以通过
ChannelHandler
对通信框架进行灵活地扩展。 - 性能高:通过与其他业界主流的
NIO
框架对比,Netty
的综合性能最优。 - 稳定:
Netty
修复了已经发现的所有NIO
的bug
,让开发人员可以专注于业务本身。 - 社区活跃:
Netty
是活跃的开源项目,版本迭代周期短,bug
修复速度快。
5、Netty的应用场景有哪些?
- 作为 RPC 框架的网络通信工具:我们在分布式系统中,不同服务节点之间经常需要相互调用,这个时候就需要
RPC
框架了。不同服务节点之间的通信是如何做的呢?可以使用Netty
来做。比如我调用另外一个节点的方法的话,至少是要让对方知道我调用的是哪个类中的哪个方法以及相关参数吧! - 实现一个自己的 HTTP 服务器:通过
Netty
我们可以自己实现一个简单的HTTP
服务器,这个大家应该不陌生。说到HTTP
服务器的话,作为Java
后端开发,我们一般使用Tomcat
比较多。一个最基本的HTTP
服务器可要以处理常见的HTTP Method
的请求,比如POST
请求、GET
请求等等。 - 实现一个即时通讯系统:使用
Netty
我们可以实现一个可以聊天类似微信的即时通讯系统,这方面的开源项目还蛮多的,可以自行去Github
找一找; - 实现消息推送系统:市面上有很多消息推送系统都是基于
Netty
来做的。
6、Netty的高性能体现再哪些方面?
- IO 线程模型:同步非阻塞,用最少的资源做更多的事;
- 内存零拷贝:尽量减少不必要的内存拷贝,实现了更高效率的传输;
- 内存池设计:申请的内存可以重用,主要指直接内存。内部实现是用一颗二叉查找树管理内存分配情况;
- 串形化处理读写:避免使用锁带来的性能开销;
- 高性能序列化协议:支持
protobuf
等高性能序列化协议。
7、Netty和Tomcat的区别?
- 作用不同:
Tomcat
是Servlet
容器,可以视为Web
服务器,而Netty
是异步事件驱动的网络应用程序框架和工具用于简化网络编程,例如TCP
和UDP
套接字服务器; - 协议不同:
Tomcat
是基于http
协议的Web
服务器,而Netty
能通过编程自定义各种协议,因为Netty
本身自己能编码/解码字节流,所有Netty
可以实现,HTTP
服务器、FTP
服务器、UDP
服务器、RPC
服务器、WebSocket
服务器、Redis
的Proxy
服务器、MySQL
的Proxy
服务器等等。
8、Netty有哪些重要组件?
- Channel:
Netty
网络操作抽象类,它除了包括基本的I/O
操作,如bind
、connect
、read
、write
等; - EventLoop:主要是配合
Channel
处理I/O
操作,用来处理连接的生命周期中所发生的事情; - ChannelFuture:Netty 框架中所有的
I/O
操作都为异步的,因此我们需要ChannelFuture
的addListener()
注册一个ChannelFutureListener
监听事件,当操作执行成功或者失败时,监听就会自动触发返回结果; - ChannelHandler:充当了所有处理入站和出站数据的逻辑容器。
ChannelHandler
主要用来处理各种事件,这里的事件很广泛,比如可以是连接、数据接收、异常、数据转换等; - ChannelPipeline:为
ChannelHandler
链提供了容器,当channel
创建时,就会被自动分配到它专属的ChannelPipeline
,这个关联是永久性的。
9、EventloopGroup 和 EventLoop 的关系?
EventLoopGroup
包含多个EventLoop
(每一个EventLoop
通常内部包含一个线程),上面我们已经说了EventLoop
的主要作用实际就是负责监听网络事件并调用事件处理器进行相关I/O
操作的处理;- 并且
EventLoop
处理的I/O
事件都将在它专有的Thread
上被处理,即Thread
和EventLoop
属于 1 : 1 的关系,从而保证线程安全; EventLoopGroup
包含Boss EventloopGroup
和Worker EventloopGroup
,其中Boss EventloopGroup
用于接收连接,Worker EventloopGroup
用于具体的处理(消息的读写以及其他逻辑处理)。
10、Bootstrap 和 ServerBootstrap的区别?
Bootstrap
通常使用connet()
方法连接到远程的主机和端口,作为一个Netty TCP
协议通信中的客户端。另外,Bootstrap
也可以通过bind()
方法绑定本地的一个端口,作为UDP
协议通信中的一端;ServerBootstrap
通常使用bind()
方法绑定本地的端口上,然后等待客户端的连接;Bootstrap
只需要配置一个线程组—EventLoopGroup
,而ServerBootstrap
需要配置两个线程组—EventLoopGroup
,一个用于接收连接,一个用于具体的处理。
11、NioEventLoopGroup 默认的构造函数会起多少线程?
// 1.bossGroup 用于接收连接,workerGroup 用于具体的处理
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
NioEventLoopGroup
默认的构造函数实际会起的线程数为 CPU
核心数*2。另外,如果你继续深入下去看构造函数的话,你会发现每个NioEventLoopGroup
对象内部都会分配一组NioEventLoop
,其大小是 nThreads
, 这样就构成了一个线程池, 一个NIOEventLoop
和一个线程相对应,这和我们上面说的 EventloopGroup
和 EventLoop
关系这部分内容相对应。
12、Netty 线程模型了解么?
大部分网络框架都是基于 Reactor 模式设计开发的。
12.1、单线程模型
12.2、多线程模型
12.3、主从Reactor模型
13、Netty 服务端和客户端的启动过程了解么?
13.1、Netty 服务端的启动过程?
13.2、Netty 客户端的启动过程?
14、什么是 TCP 粘包/拆包?
15、粘包/拆包的解决办法呢?
15.1、使用 Netty 自带的解码器
- LineBasedFrameDecoder:发送端发送数据包的时候,每个数据包之间以换行符作为分隔,
LineBasedFrameDecoder
的工作原理是它依次遍历ByteBuf
中的可读字节,判断是否有换行符,然后进行相应的截取; - DelimiterBasedFrameDecoder:可以自定义分隔符解码器,
LineBasedFrameDecoder
实际上是一种特殊的DelimiterBasedFrameDecoder
解码器; - FixedLengthFrameDecoder:固定长度解码器,它能够按照指定的长度对消息进行相应的拆包。
- LengthFieldBasedFrameDecoder:
15.2、
9、Netty 发送消息有几种方式?
- 直接写入
Channel
中,消息从 ChannelPipeline 当中尾部开始移动; - 写入和 ChannelHandler 绑定的 ChannelHandlerContext 中,消息从 ChannelPipeline 中的下一个 ChannelHandler 中移动。
10、Netty默认有多少线程?何时启动?
Netty 默认是 CPU 处理器数的两倍,bind 完之后启动。
11、Netty 支持哪些心跳类型设置?
- readerIdleTime:为读超时时间(即测试端一定时间内未接受到被测试端消息)。
- writerIdleTime:为写超时时间(即测试端一定时间内向被测试端发送消息)。
- allIdleTime:所有类型的超时时间。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统