当前位置:

首页 > 系统应用 > 从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源创计划”,欢迎正在阅读的你也加入,一起分享。

本文内容来源于网友投稿,如有侵权请联系删除。
作者最新文章
系统应用
相关文章 更多
Win11专业版和家庭版安装流程有什么区别
Win11专业版和家庭版安装流程有什么区别

Windows 11 家庭版和专业版在安装步骤上并无本质差异,主要区别在于产品密钥激活和功能解锁。本教程指导你如何检查硬件兼容性、使用官方媒体创建工具制作安装盘,以及在安装过程中正确选择版本。同时解析安装后如何验证激活状态,以及从家庭版升级到专业版的正规路径,确保系统稳定且合规。

除了界面,Windows11和Win10还有哪些实质差异
除了界面,Windows11和Win10还有哪些实质差异

除了开始菜单的变化,Windows 11在TPM 2.0安全要求、窗口贴靠布局、驱动兼容性以及系统更新策略上与Windows 10有显著不同。本文详解两者实质差异,助你判断是否值得升级。

win10专业版和家庭版关闭更新方法差别在哪
win10专业版和家庭版关闭更新方法差别在哪

详解Windows 10家庭版和专业版在关闭或暂停自动更新时的操作区别。涵盖通用的暂停更新、活动时间设置,以及专业版独有的组策略管理入口,帮助不同版本用户合理控制更新节奏,避免系统安全风险。

win10暂停更新最长可以设置多少天怎么操作
win10暂停更新最长可以设置多少天怎么操作

想知道Win10暂停更新最长能设多久?官方支持最长暂停35天。本文图文演示如何在设置中开启暂停、确认生效日期,以及到期后如何恢复更新或调整活动时间以避免打扰。

win10怎么屏蔽win10系统更新的弹窗提醒
win10怎么屏蔽win10系统更新的弹窗提醒

本教程介绍如何在Windows 10中通过暂停更新、设置活动时间及安排重启时间来减少更新弹窗提醒。包含通知隐藏技巧及更新失败排查步骤,帮助你在保持系统安全的同时减少工作打扰。

win10更新后台占用CPU过高怎么关闭自动更新
win10更新后台占用CPU过高怎么关闭自动更新

Windows 10 更新时 CPU 占用过高怎么办?本教程演示如何通过任务管理器确认更新进程,使用“暂停更新”功能临时停止后台活动,并设置“活动时间”防止自动重启干扰工作。提供安全的故障排查步骤,避免直接禁用系统服务带来的风险。

win10正在玩游戏弹出更新重启怎么禁止
win10正在玩游戏弹出更新重启怎么禁止

Win10玩游戏时突然弹出更新重启提示?不要强制关机。本文教你如何通过设置“活动时间”避免自动重启,利用“安排重启”规划空闲时间,以及合理使用“暂停更新”功能。区分不同状态下的应对策略,既保护游戏进度又维持系统安全。

win10自动更新抢占网络带宽该怎么处理
win10自动更新抢占网络带宽该怎么处理

Win10自动更新抢占带宽导致游戏卡顿或网页打不开?本教程教你通过任务管理器确认更新进程,利用暂停更新、按流量计费连接和传递优化带宽限制,精准控制Windows Update下载速度,解决网络拥堵问题。

win10家庭版有没有简单办法阻止强制更新
win10家庭版有没有简单办法阻止强制更新

Win10家庭版用户常受强制更新困扰。本文详解如何利用系统自带的暂停更新、活动时间和安排重启功能,在不破坏系统稳定性的前提下减少更新打扰,并分析注册表修改的风险及系统支持现状。

win10升级新版本后取消开机密码失效怎么修复
win10升级新版本后取消开机密码失效怎么修复

Windows 10更新后开机突然要求输入密码?本文解析自动登录失效的真实原因,提供通过netplwiz重新保存凭据、关闭Windows Hello干扰及排查账户策略的完整步骤,助你恢复免密进入桌面。

查看更多
精品专题 更多
装机必备
装机必备

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

Windows
Windows

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

macOS软件
macOS软件

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

Mac软件 更多
photoshop
photoshop
Windows、macOS 、 iPad

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

Blender
Blender
Windows、macOS 和 Linux

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

灵活计算器
灵活计算器
macOS/iOS/Android

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

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

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

photoshop
photoshop
Windows、macOS 、 iPad

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

Blender
Blender
Windows、macOS 和 Linux

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