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

当前位置:

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

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    系统应用
    相关文章 更多
    精品专题 更多
    装机必备

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

    Windows

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

    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    macOS软件

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

    IOS软件

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

    AI

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

    Mac软件 更多
    Aperty macOS版
    Aperty macOS版

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    火山引擎 网页版
    火山引擎 网页版

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    立刻MV 网页版
    立刻MV 网页版

    立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

    蛙蛙写作 网页版
    蛙蛙写作 网页版

    蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

    讯飞智作 网页版
    讯飞智作 网页版

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    超级简历WonderCV 网页版
    超级简历WonderCV 网页版

    超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

    音述AI 网页版
    音述AI 网页版

    音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

    AionClaw macOS版
    AionClaw macOS版

    AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

    Loomy macOS版
    Loomy macOS版

    Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。

    AirBuddy 3 macOS版
    AirBuddy 3 macOS版

    AirBuddy 3 是面向 macOS 的蓝牙外设增强工具,可集中查看 AirPods、Beats 与苹果设备电量,提供快速连接、播放控制、电量提醒、桌面小组件和多台 Mac 外设接力等功能。

    AirServer macOS版
    AirServer macOS版

    AirServer macOS版可把 Mac 转换为无线投屏接收端,通过 AirPlay 或 Google Cast 接收手机、平板和电脑画面,并支持多设备同时连接、高清镜像及会话录制,适合家庭娱乐、课堂教学、会议演示和应用展示。

    AnyDesk macOS版
    AnyDesk macOS版

    AnyDesk macOS版是一款适用于远程办公、设备维护和客户支持的远程桌面工具,可连接并操作异地计算机,支持文件传输、无人值守访问、会话权限控制及跨平台协作。

    WINDOWS 更多
    Aperty Windows版
    Aperty Windows版

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    火山引擎 网页版
    火山引擎 网页版

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    立刻MV 网页版
    立刻MV 网页版

    立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

    蛙蛙写作 网页版
    蛙蛙写作 网页版

    蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

    讯飞智作 网页版
    讯飞智作 网页版

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    超级简历WonderCV 网页版
    超级简历WonderCV 网页版

    超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

    音述AI 网页版
    音述AI 网页版

    音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

    AionClaw Windows版
    AionClaw Windows版

    AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

    Loomy Windows版
    Loomy Windows版

    Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。

    讯飞绘文 网页版
    讯飞绘文 网页版

    讯飞绘文网页版是科大讯飞推出的AI图文创作与内容运营工具,覆盖热点选题、文章生成、稿件校对、智能配图、排版发布和数据复盘等环节,适合自媒体创作者及内容团队在线使用。

    AirServer Windows版
    AirServer Windows版

    AirServer Windows版可把电脑变成AirPlay、Google Cast和Miracast无线投屏接收端,适合会议演示、课堂教学及家庭大屏分享。发送设备通常无需另装客户端,并可同时接收和智能排列多个镜像会话。

    AlwaysUp Windows版
    AlwaysUp Windows版

    AlwaysUp是一款面向Windows的系统服务注册与程序托管工具,可让普通应用、脚本及批处理在无人登录时随系统启动,并通过状态检测、异常重启、资源监控和邮件通知保障关键任务持续运行。