展开菜单
首页 精品内容 本月促销 装机必备 Windows macOS软件 IOS软件 Android AI PDF教程 专题
全部分类

当前位置:

首页 > 系统应用 > 从I/O多路复用到Netty,还要跨过JavaNIO包

从I/O多路复用到Netty,还要跨过JavaNIO包

本文是Netty系列第4篇上一篇文章我们深入了解了I/O多路复用的三种实现形式,select/poll/epoll。那Netty是使用哪种实现的I/O多路复用呢?这个问题,得从Ja va NIO包说起。Netty实际上也是一个封装好的框架,它的网络I/O本质上还是使用了Ja va的NIO包(New

本文是Netty系列第4篇

上一篇文章我们深入了解了I/O多路复用的三种实现形式,select/poll/epoll。

那Netty是使用哪种实现的I/O多路复用呢?这个问题,得从Ja va NIO包说起。

Netty实际上也是一个封装好的框架,它的网络I/O本质上还是使用了Ja va的NIO包(New IO,不是网络I/O模型的NIO,Nonblocking IO)包。所以,从网络I/O模型到Netty,我们还需要了解下Ja va NIO包。

本文预计阅读时间 5 分钟,将重点回答以下几个问题:

  • 如何用Ja va NIO包实现一个服务端

  • Ja va NIO包如何实现I/O多路复用模型

  • 有了Ja va NIO包,为什么还要封装一个Netty?

1.先来看一个Ja va NIO服务端的例子

上一篇文章我们已经了解了I/O多路复用的实现形式。
就是多个的进程的IO可以注册到一个复用器(selector)上,然后用一个进程调用select,select会监听所有注册进来的IO。

NIO包做了对应的实现。如下图所示。

存在一个统一的selector,负责对所有Channel进行监听。只要这些channel中有任何一个发生了IO动作,都能通过Selector.select()方法检测到。然后,利用selectedKeys就能获取到这些发生IO的channel,进而对它们执行相应的IO操作。

我们来个简单的demo做一下演示。如何使用NIO中三个核心组件(Buffer缓冲区、Channel通道、Selector选择器)来编写一个服务端程序。

public class NioDemo {
public static void main(String[] args) {
try {
//1.创建channel
ServerSocketChannel socketChannel1 = ServerSocketChannel.open();
//设置为非阻塞模式,默认是阻塞的
socketChannel1.configureBlocking(false);
socketChannel1.socket().bind(new InetSocketAddress("127.0.0.1", 8811));

ServerSocketChannel socketChannel2 = ServerSocketChannel.open();
socketChannel2.configureBlocking(false);
socketChannel2.socket().bind(new InetSocketAddress("127.0.0.1", 8822));

//2.创建selector,并将channel1和channel2进行注册。
Selector selector = Selector.open();
socketChannel1.register(selector, SelectionKey.OP_ACCEPT);
socketChannel2.register(selector, SelectionKey.OP_ACCEPT);

while (true) {
//3.一直阻塞直到有至少有一个通道准备就绪
int readChannelCount = selector.select();
Set selectionKeys = selector.selectedKeys();
Iterator iterator = selectionKeys.iterator();
//4.轮训已经就绪的通道
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
iterator.remove();
//5.判断准备就绪的事件类型,并作相应处理
if (key.isAcceptable()) {
// 创建新的连接,并且把连接注册到selector上,并且声明这个channel只对读操作感兴趣。
ServerSocketChannel serverSocketChannel = (ServerSocketChannel)key.channel();
SocketChannel socketChannel = serverSocketChannel.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
}
if (key.isReadable()) {
SocketChannel socketChannel = (SocketChannel) key.channel();
ByteBuffer readBuff = ByteBuffer.allocate(1024);
socketChannel.read(readBuff);
readBuff.flip();
System.out.println("received : " + new String(readBuff.array()));
socketChannel.close();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

通过这个代码示例,我们能清楚地了解如何用Ja va NIO包实现一个服务端:

  • 1)创建channel1和channel2,分别监听特定端口。

  • 2)创建selector,并将channel1和channel2进行注册。

  • 3)selector.select()一直阻塞,直到有至少有一个通道准备就绪。

  • 4)轮训已经就绪的通道

  • 5)并根据事件类型做出相应的响应动作。

程序启动后,会一直阻塞在selector.select()。
通过浏览器调用localhost:8811 或者 localhost:8822就能触发我们的服务端代码了。

2.Ja va NIO包如何实现I/O多路复用模型

上文演示的Ja va NIO服务端已经比较清楚地展示了使用NIO编写服务端程序的过程。

那这个过程中如何实现了I/O多路复用的呢?

我们得深入看下selector的实现。

//2.创建selector,并将channel1和channel2进行注册。
Selector selector = Selector.open();

从open这里开始吧。

这里用了一个SelectorProvider来创建selector。

进入SelectorProvider.provider(),看到具体的provider是由
sun.nio.ch.DefaultSelectorProvider创建的,对应的方法是:

咦?原来不同的操作系统会提供不同的provider对象。这里包括了PollSelectorProvider、EPollSelectorProvide等。

名字是不是有点眼熟?

没错,跟我们上一篇文章分析过的I/O多路复用的不同实现方式poll/epoll有关。

我们选择默认的
sun.nio.ch.PollSelectorProvider往下看看。

OK,找到了实现类PollSelectorImpl。

然后,通过以下调用:

找到最终的native方法poll0。

是不是仍然很眼熟?

没错!跟我们上一篇文章分析过的poll函数是一致的。

int poll (struct pollfd *fds, unsigned int nfds, int timeout);

绕了这么久,到最后,还是找到了我们聊过I/O多路复用的 poll 实现。

至此,我们终于把Ja va NIO和 I/O多路复用模型串联起来了。

Ja va NIO包使用selector,实现了I/O多路复用模型。

同时,在不同的操作系统中,会有不同的poll/epoll选择。

3.为什么还需要Netty呢?

那既然已经有了NIO包了,我们可以自己手动编写服务框架了,为什么还需要封装一个Netty框架呢?有什么好处呢?

好处当然是有很多了!我们从一开始实现的demo说起。

3.1 设计模式的优化

我们的demo确实已经能够工作了,但是还是有比较明显的问题。第4步(轮询已经就绪的通道)和第5步(对事件作相应处理)是在同一个线程中的,当事件处理比较耗时甚至阻塞时,整个流程就会阻塞了。

我们使用的实际上就是“单Reactor单线程”设计模式。

这种模型在Reactor中负责监听端口、接收请求,如果是连接事件交给acceptor处理,如果是读写事件和业务处理就交给handler处理,但始终只有一个线程执行所有的事情。

为了提高性能,我们理所当然相当可以把事件处理交给线程池,那就可以演进为“单Reactor多线程”设计模式。

这种模型和第一种模型的主要区别是把业务处理从之前的单一线程脱离出来,换成线程池处理。Reactor线程只处理连接事件、读写事件,所有业务处理都交给线程池,充分利用多核机器的资源,提高性能。

但是这仍然不够!

我们可以发现,一个Reactor线程承担了所有的网络事件,例如监听和响应,高并发场景下单线程存在性能问题。

为了充分利用多核能力,可以构建两个 Reactor,主 Reactor 单独监听server socket,accept新连接,然后将建立的 SocketChannel 注册给指定的从 Reactor,从Reactor再执行事件的读写、分发,把业务处理就扔给worker线程池完成。这就演进为”主从Reactor模式“设计模式。

所以,如果有人直接帮我们封装好这样的设计模式,是不是太好了?

没错,Netty就是这样的“活雷锋”!
Netty就使用了主从Reactor模式封装了Ja va NIO包的使用,大大提高了性能。

3.2 其他优点 (以后的核心知识点)

除了封装了高性能的设计模式外,Netty还有许多其他优点:

  • 稳定性。Netty 更加可靠稳定,修复和完善了 JDK NIO 较多已知问题,包括 select 空转导致 CPU 消耗 100%、keep-alive 检测等问题。

  • 性能优化方面,对象池复用技术功不可没。Netty通过复用对象,避免了频繁创建和销毁所带来的开销。还有零拷贝技术,除了操作系统级别的,Netty还提供了面向用户态的零拷贝技术,在I/O读写时直接使用DirectBuffer,这样就避免了数据在堆内存和堆外内存之间的拷贝。

  • 便捷性。Netty 提供了很多常用的工具,例如行解码器、长度域解码器等。如果我们使用JDK NIO包,那么这些常用工具都需要自己进行实现。

正是因为 Netty 做到了高性能、高稳定性、高易用性,完美弥补了 Ja va NIO 的不足,所以在我们在网络编程时,首选Netty,而不是自己直接使用Ja va NIO。

回顾一下前几章内容,到目前为止,我们从网络I/O模型出发,一步步了解到了Netty的网络I/O模型。

对于I/O多路复用、Ja va NIO包 和 Netty 的关系也有了全面的认识。

有了这些知识基础,我们初步了解了Netty是什么,为什么使用Netty。

后面的文章,我们将逐步展开Netty框架的核心知识点,敬请期待。

往期热门笔记合集推荐:

  • HBase原理与实战笔记合集

  • MySQL实战笔记合集

  • Canal/Otter源码与实战笔记合集

  • Ja va实战技巧笔记合集

扫描下方二维码可以关注我哦~

觉得不错,就点个 再看吧

如果有任何疑问或者建议,欢迎写留言或者 微信 和我联系哦~

本文分享自微信公众号 - 阿丸笔记(aone_note)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

本文内容来源于网友投稿,如有侵权请联系删除。
作者最新文章
系统应用
相关文章 更多
精品专题 更多
装机必备

正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

Windows

正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

macOS软件

正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

IOS软件

正软商城iOS软件专区,精选适用于iPhone和iPad的办公、学习、影音、设计、效率及AI应用,提供功能介绍、适用设备、系统要求和正版获取方式等信息。

AI

正软商城AI软件专区,汇集AI写作、AI绘画、AI视频、AI办公、AI编程、AI翻译、智能客服和数据分析等人工智能工具,提供功能介绍、适用平台、收费方式及正版购买信息。

Mac软件 更多
photoshop
photoshop

Photoshop 2026 是 Adobe 推出的专业图像处理与视觉设计软件,支持 Windows、macOS 和 iPad 等平台,广泛应用于摄影修图、电商设计、平面海报、数字绘画及视觉合成等创作场景。

Blender
Blender

Blender 是一款免费开源、跨平台的专业 3D 创作软件,集建模、动画、渲染、视频编辑与视觉合成等功能于一体,广泛应用于影视动画、游戏设计和建筑可视化等领域。软件支持 Cycles 物理渲染器与 Eevee 实时渲染引擎,并提供多边形建模、骨骼绑定、物理模拟等专业工具。Blender 兼容 Windows、macOS 和 Linux 系统,安装包轻巧、运行流畅,依托活跃的全球开发者社区持续更新,是从初学者到专业创作者都值得选择的正版 3D 创作工具。

灵活计算器
灵活计算器

灵活计算器是一款笔记式算数应用,支持实时计算、动态关联和云端同步功能。记录、整理和输出之间的过渡会更自然,适合长期写作、做笔记或持续沉淀个人内容。

赤友清理大师
赤友清理大师

赤友清理大师是一款为 Mac 设计的智能清理优化工具,可精准扫描垃圾、大文件、重复文件等,释放磁盘空间。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

极度公式
极度公式

极度公式是一款跨平台专业LaTeX公式识别编辑软件,支持OCR公式识别和多平台编辑。和使用说明,避免使用,享受完整功能与稳定支持。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

图几
图几

图几是一款适用于 macOS 的截图、标注与美化工具,支持离线操作保障隐私。界面整理和高频系统操作被放到一起考虑,桌面或窗口内容一多时,管理起来会更省心。

密码键盘
密码键盘

密码键盘是一款兼具安全性与便捷性的高效密码管理器。日常使用里的持续防护和信息管理会更突出,适合把安全控制放进长期使用流程中的场景。

思源笔记
思源笔记

思源笔记是一款本地笔记软件,提供所见即所得的编辑方式,为长文写作带来顺滑的体验。记录、整理和输出之间的过渡会更自然,适合长期写作、做笔记或持续沉淀个人内容。

Office 365 简体中文
Office 365 简体中文

一款文字处理软件,一种订阅式的跨平台办公软件,基于云平台提供多种服务,通过将 Excel 和 Outlook 等应用与 OneDrive 和 Microsoft Teams 等强大的云服务相结合,Office 365 可让任何人使用任何设备随时随地创建和共享内容。

Mac
WALTR PRO
WALTR PRO

WALTR是一款电脑至iOS文件传输转换工具,操作简单,快速实现文件识别与传送。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

CodeExpander
CodeExpander

CodeExpander 是一款快捷短语输入增强工具,通过键入缩写自动展开为自定义文段,提升工作效率。任务管理和过程控制会更完整,持续下载、批量同步或需要稳定传输流程的场景会更适合它。

Mountain Duck
Mountain Duck

Mountain Duck 是一款能将多个网盘挂载到本地的工具,像本地磁盘一样使用网盘。清理链路的完整性会更好一些,做应用卸载、残留处理和空间整理时,通常能少走很多手动排查步骤。

WINDOWS 更多
3dmax(3ds max)
3dmax(3ds max)

Autodesk 3ds Max 是一款专业的三维建模、动画与渲染软件,广泛应用于建筑可视化、游戏开发、影视动画、广告设计和产品展示等领域。

photoshop
photoshop

Photoshop 2026 是 Adobe 推出的专业图像处理与视觉设计软件,支持 Windows、macOS 和 iPad 等平台,广泛应用于摄影修图、电商设计、平面海报、数字绘画及视觉合成等创作场景。

Blender
Blender

Blender 是一款免费开源、跨平台的专业 3D 创作软件,集建模、动画、渲染、视频编辑与视觉合成等功能于一体,广泛应用于影视动画、游戏设计和建筑可视化等领域。软件支持 Cycles 物理渲染器与 Eevee 实时渲染引擎,并提供多边形建模、骨骼绑定、物理模拟等专业工具。Blender 兼容 Windows、macOS 和 Linux 系统,安装包轻巧、运行流畅,依托活跃的全球开发者社区持续更新,是从初学者到专业创作者都值得选择的正版 3D 创作工具。

Windows 10
Windows 10

Windows 10 是一款微软推出的经典操作系统,拥有硬件兼容性与多任务处理能力。它更偏向把系统状态查看和常用调节动作放在一起,适合需要持续观察和微调设备状态的场景。

极度公式
极度公式

极度公式是一款跨平台专业LaTeX公式识别编辑软件,支持OCR公式识别和多平台编辑。和使用说明,避免使用,享受完整功能与稳定支持。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

密码键盘
密码键盘

密码键盘是一款兼具安全性与便捷性的高效密码管理器。日常使用里的持续防护和信息管理会更突出,适合把安全控制放进长期使用流程中的场景。

思源笔记
思源笔记

思源笔记是一款本地笔记软件,提供所见即所得的编辑方式,为长文写作带来顺滑的体验。记录、整理和输出之间的过渡会更自然,适合长期写作、做笔记或持续沉淀个人内容。

傲梅轻松备份
傲梅轻松备份

傲梅轻松备份是一款专业易用的数据备份软件,为重要数据提供安全保障。日常使用里的持续防护和信息管理会更突出,适合把安全控制放进长期使用流程中的场景。

Office 365 简体中文
Office 365 简体中文

一款文字处理软件,一种订阅式的跨平台办公软件,基于云平台提供多种服务,通过将 Excel 和 Outlook 等应用与 OneDrive 和 Microsoft Teams 等强大的云服务相结合,Office 365 可让任何人使用任何设备随时随地创建和共享内容。

Mac
Wise Folder Hider Pro
Wise Folder Hider Pro

Wise Folder Hider Pro 是一款专业级文件和文件夹隐藏加密软件,为私密数据添加多重保护。高频操作更强调就近处理,浏览、整理和跨目录移动文件时,来回切换和重复点击都会少很多。

WALTR PRO
WALTR PRO

WALTR是一款电脑至iOS文件传输转换工具,操作简单,快速实现文件识别与传送。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

CodeExpander
CodeExpander

CodeExpander 是一款快捷短语输入增强工具,通过键入缩写自动展开为自定义文段,提升工作效率。任务管理和过程控制会更完整,持续下载、批量同步或需要稳定传输流程的场景会更适合它。