九月十月黄金季,你对Netty的必备核心知识掌握了多少呢?
小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
前言
作为一名Java中高级开发,不会Netty都不好意思出去面试,现在正值一些小伙伴找工作的的时间,我相信你面试的过程肯定有面试官会问到Netty的知识点,本篇文章就为小伙伴整理一下Netty的核心知识点,希望你们面试都能成功拿到自己满意的薪资。
本人收集了一些简历模板资料,希望对小伙伴们有帮助:
百度云盘:
链接:
https://pan.baidu.com/s/1Xr-uIzhdDBo4qxMQ7kITCQ
提取码:y9jq
关于怎么写简历,我上午看到这篇文章写得挺好的,分享给你们,链接如下:
简历写得好,工作找得早,程序员的秋招简历指南!
正文
BIO、NIO 和 AIO
-
BIO:俗称同步阻塞 IO,一种非常传统的 IO 模型。简单来说,在服务器中
BIO
是一个连接由一个专门的线程来服务的工作模式。 -
NIO:一种同步非阻塞的 I/O 模型。简单来说,客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。
-
AIO:采用
订阅-通知
模式,即应用程序向操作系统注册IO监听,然后继续做自己的事情。当操作系统发生IO事件,并且准备好数据后,在主动通知应用程序,触发相应的函数。
详细的介绍可以看我之前的文章,相关连接如下:
深入分析 Java IO (二)BIO
深入分析 Java IO (三)NIO
深入分析 Java IO (四)AIO
Netty是什么?为什么要用 Netty?
Netty 是由 JBOSS 提供的一个 Java 开源框架。Netty 提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。
虽然JAVA NIO
和 JAVA AIO
框架提供了多路复用IO/异步IO的支持,但是并没有提供上层“信息格式”的良好封装。用这些API实现一款真正的网络应用则并非易事。
JAVA NIO
和 JAVA AIO
并没有提供断连重连、网络闪断、半包读写、失败缓存、网络拥塞和异常码流等的处理,这些都需要开发者自己来补齐相关的工作。
AIO
在实践中,并没有比NIO
更好。AIO
在不同的平台有不同的实现,windows系统下使用的是一种异步IO技术:IOCP
;Linux下由于没有这种异步 IO 技术,所以使用的是epoll
对异步 IO 进行模拟。所以 AIO 在 Linux 下的性能并不理想。AIO 也没有提供对 UDP 的支持。
综上,在实际的大型互联网项目中,Java 原生的 API 应用并不广泛,取而代之的是一款第三方Java 框架,这就是Netty
。
详细的介绍可以看我之前的文章:
Netty 源码分析系列(二)Netty 架构设计
Netty 源码分析系列(一)Netty 概述
Netty的线程模型
Netty 通过 Reactor 模型基于多路复用器接收并处理用户请求,内部实现了两个线程池,boss线程池和work线程池,其中boss线程池的线程负责处理请求的 accept 事件,当接收到 accept 事件的请求时,把对应的socket封装到一个
NioSocketChannel
中,并交给 work线程池,其中 work线程池负责请求的read
和write
事件,由对应的Handler处理。
详细的介绍可以看我之前的文章:Netty 源码分析系列(十)Reactor 模型
Netty 的零拷贝了解么?
在 OS 层面上的 Zero-copy 通常指避免在 用户态(User-space) 与 内核态(Kernel-space) 之间来回拷贝数据。而在 Netty 层面 ,零拷贝主要体现在对于数据操作的优化。
- 使用 Netty 提供的 CompositeByteBuf 类,可以将多个ByteBuf 合并为一个逻辑上的 ByteBuf,避免了各个 ByteBuf 之间的拷贝。
- ByteBuf 支持 slice 操作,因此可以将 ByteBuf 分解为多个共享同一个存储区域的 ByteBuf,避免了内存的拷贝。
- 通过 FileRegion 包装的
FileChannel.tranferTo
实现文件传输,可以直接将文件缓冲区的数据发送到目标 Channel,避免了传统通过循环 write 方式导致的内存拷贝问题。
详细的介绍可以看我之前的文章,相关链接如下:
一文彻底弄懂零拷贝原理
Netty 源码分析系列(八)Netty 如何实现零拷贝
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,这个关联是永久性的。
- Bootstrap:主要用于配置服务端或客户端的 Netty 程序的启动信息。
- ByteBuf:字节数据容器,提供比
Java NIO ByteBuffer
更好的的 API。
详细的介绍可以看我之前的文章,相关链接如下:
Netty 源码分析系列(三)Channel 概述
Netty 源码分析系列(四)ChannelHandler
Netty 源码分析系列(五)ChannelPipeline源码分析
Netty 源码分析系列(六)字节缓冲区 ByteBuf(上)
Netty 源码分析系列(七)字节缓冲区 ByteBuf(下)
Netty 源码分析系列(九)Netty 程序引导类
什么是 TCP 粘包/拆包?有什么解决办法呢?
TCP 是以流的方式来处理数据,一个完整的包可能会被 TCP 拆分成多个包进行发送,也可能把小的封装成一个大的数据包发送。 TCP 粘包/分包的原因:应用程序写入的字节大小大于套接字发送缓冲区的大小,会发生拆包现象,而应用程序写入数据小于套接字缓冲区大小,网卡将应用多次写入的数据发送到网络上,这将会发生粘包现象; 进行 MSS 大小的 TCP 分段,当 TCP 报文长度-TCP 头部长度 >MSS 的时候将发生拆包 以太网帧的 payload(净荷)大于 MTU(1500 字节)进行 ip 分片。
解决的方法:
1.使用 Netty 自带的解码器
(1)通过FixedLengthFrameDecoder
定长解码器来解决定长消息的黏包问题;
(2)通过LineBasedFrameDecoder
和StringDecoder
来解决以回车换行符作为消息结束符的TCP黏包的问题;
(3)通过DelimiterBasedFrameDecoder
特殊分隔符解码器来解决以特殊符号作为消息结束符的TCP黏包问题;
(4)通过LengthFieldBasedFrameDecoder
自定义长度解码器解决TCP黏包问题。
2.自定义序列化编解码器
通常情况下,我们使用 Protostuff、Hessian2、json 序列方式比较多,另外还有一些序列化性能非常好的序列化方式也是很好的选择。
关于编解码器的介绍,可以看我之前的文章,相关链接如下:
Netty 源码分析系列(十二)Netty 解码器
Netty 源码分析系列(十三)Netty 编码器
Netty 源码分析系列(十四)Netty 编解码器
Netty 源码分析系列(十五)自定义解码器、编码器、编解码器
Netty的工作原理
下图就是 Netty 的工作原理图:
详细的介绍可以看我之前的文章,相关链接:Netty 源码分析系列(十一)Netty 工作原理详解
小结
其实在学习 Netty 源码之前,首先要让自己成为一个熟练工,掌握基本理论。然后再去学习相关的博客、源码等资源。希望上面这份Netty笔记能够帮助到有需要的小伙伴!
看完记得点赞、关注、收藏哟!!!
上一篇: 必备的 Netty 面试知识点速览
下一篇: 全面梳理Netty面试必知问题集锦