阅读 666

金九银十,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 NIOJAVA AIO框架提供了多路复用IO/异步IO的支持,但是并没有提供上层“信息格式”的良好封装。用这些API实现一款真正的网络应用则并非易事。

JAVA NIOJAVA 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线程池负责请求的readwrite事件,由对应的Handler处理。

详细的介绍可以看我之前的文章:Netty 源码分析系列(十)Reactor 模型

Netty 的零拷贝了解么?

在 OS 层面上的 Zero-copy 通常指避免在 用户态(User-space) 与 内核态(Kernel-space) 之间来回拷贝数据。而在 Netty 层面 ,零拷贝主要体现在对于数据操作的优化。

  1. 使用 Netty 提供的 CompositeByteBuf 类,可以将多个ByteBuf 合并为一个逻辑上的 ByteBuf,避免了各个 ByteBuf 之间的拷贝。
  2. ByteBuf 支持 slice 操作,因此可以将 ByteBuf 分解为多个共享同一个存储区域的 ByteBuf,避免了内存的拷贝。
  3. 通过 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)通过LineBasedFrameDecoderStringDecoder来解决以回车换行符作为消息结束符的TCP黏包的问题;

(3)通过DelimiterBasedFrameDecoder 特殊分隔符解码器来解决以特殊符号作为消息结束符的TCP黏包问题;

(4)通过LengthFieldBasedFrameDecoder 自定义长度解码器解决TCP黏包问题。

2.自定义序列化编解码器

通常情况下,我们使用 Protostuff、Hessian2、json 序列方式比较多,另外还有一些序列化性能非常好的序列化方式也是很好的选择。

关于编解码器的介绍,可以看我之前的文章,相关链接如下:

Netty 源码分析系列(十二)Netty 解码器

Netty 源码分析系列(十三)Netty 编码器

Netty 源码分析系列(十四)Netty 编解码器

Netty 源码分析系列(十五)自定义解码器、编码器、编解码器

Netty的工作原理

下图就是 Netty 的工作原理图:

image-20210815210630321

详细的介绍可以看我之前的文章,相关链接:Netty 源码分析系列(十一)Netty 工作原理详解

小结

其实在学习 Netty 源码之前,首先要让自己成为一个熟练工,掌握基本理论。然后再去学习相关的博客、源码等资源。希望上面这份Netty笔记能够帮助到有需要的小伙伴!

看完记得点赞、关注、收藏哟!!!

文章分类
后端
文章标签