【Netty篇】EventLoopGroup 与 EventLoop 详解

news2025/4/19 10:32:02

在这里插入图片描述

目录

    • 开场白:话说 Netty 江湖
    • 第一段:EventLoopGroup——“包工头”的角色
    • 第二段:EventLoop——“身怀绝技的工人”
    • 第三段:EventLoop 如何处理 I/O 事件、普通任务和定时任务
    • 第四段:Handler 执行中如何换人?
    • 总结:EventLoop 和 EventLoopGroup 的关系

🌟我的其他文章也讲解的比较有趣😁,如果喜欢博主的讲解方式,可以多多支持一下,感谢🤗!

🌟了解 Java的 NIO 请看 : NIO,看完你就懂了!

其他优质专栏: 【🎇SpringBoot】【🎉多线程】【🎨Redis】【✨设计模式专栏(已完结)】…等

如果喜欢作者的讲解方式,可以点赞收藏加关注,你的支持就是我的动力
✨更多文章请看个人主页: 码熔burning

接下来,咱们这就来一场 Netty 的“相声大会”,主角就是 EventLoop 和 EventLoopGroup 这俩活宝!保证你听完之后,不仅能明白它们是干啥的,还能自己上手耍两把。😎

开场白:话说 Netty 江湖

话说这 Netty 江湖,高手如云,但要说最核心的,还得是 EventLoop 和 EventLoopGroup 这哥俩。它们就像是 Netty 的“心脏”和“大脑”,负责处理各种“江湖事务”,让 Netty 这个“武林高手”能轻松应对各种挑战。💪

了解Netty请看:【Netty篇】幽默的讲解带你入门 Netty !建议收藏

第一段:EventLoopGroup——“包工头”的角色

  • EventLoopGroup 是啥?

    你可以把 EventLoopGroup 想象成一个“包工头”,它手底下管着一群“工人”,也就是 EventLoop。它的主要职责是:

    • 招兵买马: 创建并管理 EventLoop。 🐴
    • 分配任务: 接收各种“任务”(比如客户端连接、数据读写),然后把这些任务分配给手下的 EventLoop 去处理。 📝
    • 统筹全局: 负责整个线程池的生命周期管理,比如启动、关闭等等。 💼
  • EventLoopGroup 的种类

    Netty 提供了两种常用的 EventLoopGroup(当然还有很多其他的,这里就不举例了):

    • NioEventLoopGroup: 这是最常用的,基于 NIO(Non-blocking I/O)实现,适合处理高并发的网络应用。你可以把它想象成一群“身手敏捷的忍者”,擅长处理各种异步 I/O 事件。
    • EpollEventLoopGroup: 在 Linux 系统上,如果安装了 epoll,可以使用这个,性能更好。你可以把它想象成“开了外挂的忍者”,速度更快,效率更高。 🚀
  • EventLoopGroup 的使用

    // 创建一个 NioEventLoopGroup,包含 4 个 EventLoop
    EventLoopGroup bossGroup = new NioEventLoopGroup(1); // 通常 bossGroup 线程数设置为 1 即可
    EventLoopGroup workerGroup = new NioEventLoopGroup(); // 默认线程数是 CPU 核心数 * 2
    
    try {
        ServerBootstrap b = new ServerBootstrap();
        b.group(bossGroup, workerGroup) // 设置 bossGroup 和 workerGroup
         .channel(NioServerSocketChannel.class) // 指定使用 NIO 的 ServerSocketChannel
         .childHandler(new ChannelInitializer<SocketChannel>() { // 设置 ChannelHandler
             @Override
             public void initChannel(SocketChannel ch) throws Exception {
                 ch.pipeline().addLast(new MyHandler()); // 添加自定义的 Handler
             }
         });
    
        // 绑定端口,开始接收连接
        ChannelFuture f = b.bind(8080).sync();
    
        // 等待服务器 socket 关闭
        f.channel().closeFuture().sync();
    } finally {
        workerGroup.shutdownGracefully();
        bossGroup.shutdownGracefully();
    }
    

    这段代码里,bossGroup 负责处理客户端的连接请求,workerGroup 负责处理连接建立后的 I/O 事件。

第二段:EventLoop——“身怀绝技的工人”

  • EventLoop 是啥?

    EventLoop 就像是 EventLoopGroup 手下的“工人”,每个 EventLoop 都是一个单线程执行器,负责:

    • 监听 I/O 事件: 通过 Selector 监听 Channel 上的各种 I/O 事件,比如连接建立、数据可读、数据可写等等。 👂
    • 处理 I/O 事件: 当有 I/O 事件发生时,EventLoop 会负责读取数据、写入数据,并调用 ChannelHandler 进行业务处理。 🛠️
    • 执行普通任务: 除了 I/O 事件,EventLoop 还可以执行一些普通的任务,比如用户自定义的业务逻辑。 👨‍💻
    • 执行定时任务: EventLoop 还可以执行定时任务,比如定时发送心跳包、定时清理过期数据等等。 ⏰
  • EventLoop 的特点

    • 单线程: 每个 EventLoop 都是一个单线程,这意味着所有任务都是串行执行的,避免了多线程并发带来的锁竞争问题。 🧵
    • 非阻塞: EventLoop 通过 NIO 的 Selector 监听 I/O 事件,当没有事件发生时,线程会阻塞在 Selector 上,不会占用 CPU 资源。 😴
    • 事件驱动: EventLoop 通过事件驱动的方式处理 I/O 事件,当有事件发生时,才会执行相应的处理逻辑。 🚦
  • EventLoop 的使用

    EventLoop 的使用通常是隐式的,你不需要直接操作 EventLoop,Netty 会自动把任务分配给 EventLoop 去执行。

    // 在 ChannelHandler 中执行任务
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        // 提交一个任务给 EventLoop 执行
        ctx.executor().execute(() -> {
            try {
                Thread.sleep(1000);
                System.out.println("处理耗时任务:" + msg);
                ctx.writeAndFlush(msg);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
    }
    

    这段代码里,ctx.executor() 返回的就是当前 Channel 绑定的 EventLoop,你可以通过 execute() 方法提交一个任务给 EventLoop 执行。

第三段:EventLoop 如何处理 I/O 事件、普通任务和定时任务

  • 处理 I/O 事件

    1. 监听事件: EventLoop 通过 Selector 监听 Channel 上的 I/O 事件。 📡
    2. 事件就绪: 当有 I/O 事件就绪时,Selector 会通知 EventLoop。 🔔
    3. 读取事件: EventLoop 从 Selector 中读取就绪的 I/O 事件。 📚
    4. 处理事件: EventLoop 根据事件类型,执行相应的处理逻辑,比如读取数据、写入数据、调用 ChannelHandler 等等。 ⚙️
  • 处理普通任务

    你可以通过 EventLoop.execute() 方法提交一个普通任务给 EventLoop 执行。EventLoop 会把这些任务放入一个队列中,然后按照 FIFO(先进先出)的顺序执行。 ➡️

    NioEventLoopGroup nioWorkers = new NioEventLoopGroup(2);
    
    log.debug("server start...");
    Thread.sleep(2000);
    nioWorkers.execute(()->{
        log.debug("normal task...");
    });
    

    输出:

    22:30:36 [DEBUG] [main] c.i.o.EventLoopTest2 - server start...
    22:30:38 [DEBUG] [nioEventLoopGroup-2-1] c.i.o.EventLoopTest2 - normal task...
    

    可以用来执行耗时较长的任务。

  • 处理定时任务

    你可以通过 EventLoop.schedule()EventLoop.scheduleAtFixedRate() 方法提交一个定时任务给 EventLoop 执行。EventLoop 会把这些定时任务放入一个定时任务队列中,然后按照时间顺序执行。

    // 提交一个定时任务给 EventLoop 执行
    ctx.executor().schedule(() -> {
        System.out.println("定时任务执行了");
        ctx.writeAndFlush("心跳包");
    }, 5, TimeUnit.SECONDS);
    

第四段:Handler 执行中如何换人?

在 Netty 的 ChannelPipeline 中,Handler 的执行顺序是按照添加的顺序依次执行的。但是,在 Handler 的执行过程中,你可以通过以下方式“换人”:

  • ctx.fireChannelRead(msg) 这个方法会把消息传递给 Pipeline 中的下一个 InboundHandler。你可以把它想象成“传球”,把消息传递给下一个 Handler 去处理。 ⚽
  • ctx.writeAndFlush(msg) 这个方法会把消息传递给 Pipeline 中的 OutboundHandler,然后把数据写入 Channel。你可以把它想象成“射门”,把消息发送出去。 🥅
  • ctx.pipeline().remove(handler) 这个方法会从 Pipeline 中移除指定的 Handler。你可以把它想象成“换人”,把不需要的 Handler 移除掉。 ❌
  • ctx.pipeline().replace(oldHandler, newHandler) 这个方法会用新的 Handler 替换旧的 Handler。你可以把它想象成“换人”,用新的 Handler 替换旧的 Handler。 🔄

总结:EventLoop 和 EventLoopGroup 的关系

EventLoopGroup 就像是一个“包工头”,负责创建和管理 EventLoop。EventLoop 就像是“工人”,负责处理 I/O 事件、普通任务和定时任务。它们之间的关系就像是“领导”和“员工”,互相配合,共同完成任务。🤝

结尾:Netty 江湖,等你来闯

好了,今天的 Netty “相声大会”就到这里。希望通过这种幽默的方式,让你对 EventLoop 和 EventLoopGroup 有了更深入的了解。Netty 江湖,等你来闯! 🎉

补充说明:

  • 线程模型: Netty 的线程模型是 Reactor 模式,EventLoop 就是 Reactor 模式中的 Reactor。 ⚛️
  • 性能优化: 合理配置 EventLoopGroup 的线程数,可以提高 Netty 的性能。通常情况下,bossGroup 的线程数设置为 1 即可,workerGroup 的线程数设置为 CPU 核心数 * 2。 📈
  • 异常处理: 在 ChannelHandler 中,一定要注意处理异常,避免因为一个 Handler 出现异常而导致整个 Pipeline 崩溃。 ⚠️

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2336393.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

操作系统之shell实现(上)

&#x1f31f; 各位看官好&#xff0c;我是maomi_9526&#xff01; &#x1f30d; 种一棵树最好是十年前&#xff0c;其次是现在&#xff01; &#x1f680; 今天来学习C语言的相关知识。 &#x1f44d; 如果觉得这篇文章有帮助&#xff0c;欢迎您一键三连&#xff0c;分享给更…

数据结构与算法——链表OJ题详解(2)

文章目录 一、前言二、OJ续享2.1相交链表2.2环形链表12.2环形链表2 三、总结 一、前言 哦了兄弟们&#xff0c;咱们上次在详解链表OJ题的时候&#xff0c;有一部分OJ题呢up并没有整理完&#xff0c;这一个星期呢&#xff0c;up也是在不断的学习并且沉淀着&#xff0c;也是终于…

Linux 基础知识详解

Linux 基础知识详解 一、快照与克隆 1. &#x1f4f8;快照&#xff08;Snapshot&#xff09; 快照是虚拟机当前运行状态的一次“瞬间拷贝”&#xff0c;包括内存、磁盘、配置等信息。这使得管理员能够快速恢复到某个特定的时间点。 用途&#xff1a; 安全实验前保存状态&am…

centOs7配置有限网络

最简单快速的是使用nmtui命令&#xff0c;采用图形页面修改。 点击编辑连接并回车&#xff1a; 选中编辑然后回车&#xff1a; 千万记住DNS服务器就是子网掩码&#xff0c;不是常说的DNS域名。把地址&#xff0c;网关&#xff0c;子网掩码配置好。只要ip不冲突&#xff0c;网…

C语言 —— 指尖跃迁 刻印永恒 - 文件操作

目录 1. 什么是文件 1.1 程序文件 1.2 数据文件 1.3 文件名 2. 二进制文件和文本文件 3. 文件的打开与关闭 3.1 流和标准流 3.2 文件指针 3.3 文件的打开与关闭 fopen fclose 4. 文件的顺序读写 4.1 fgetc和fputc fgetc fputc 4.2 fgets和fputs fgets fputs…

网络安全与信息安全的区别​及共通

在数字化时代&#xff0c;网络安全与信息安全已成为保障个人、企业乃至国家正常运转的重要防线。尽管二者紧密相关且常被混为一谈&#xff0c;但实则存在显著差异。当然&#xff0c;它们也有一些相同点&#xff0c;比如都以保障数字环境下的安全为核心目标&#xff0c;均需要通…

【愚公系列】《Python网络爬虫从入门到精通》052-Scrapy 编写 Item Pipeline

&#x1f31f;【技术大咖愚公搬代码&#xff1a;全栈专家的成长之路&#xff0c;你关注的宝藏博主在这里&#xff01;】&#x1f31f; &#x1f4e3;开发者圈持续输出高质量干货的"愚公精神"践行者——全网百万开发者都在追更的顶级技术博主&#xff01; &#x1f…

【AI News | 20250416】每日AI进展

AI Repos 1、Tutorial-Codebase-Knowledge 自动分析 GitHub 仓库并生成适合初学者的通俗易懂教程&#xff0c;清晰解释代码如何运行&#xff0c;还能生成可视化内容来展示核心功能。爬取 GitHub 仓库并从代码中构建知识库&#xff1b;分析整个代码库以识别核心抽象概念及其交互…

GIS开发笔记(6)结合osg及osgEarth实现半球形区域绘制

一、实现效果 输入中心点坐标及半径&#xff0c;绘制半球形区域&#xff0c;地下部分不显示。 二、实现原理 根据中心点及半径绘制半球形区域&#xff0c;将其挂接到地球节点。 三、参考代码 void GlobeWidget::drawSphericalRegion(osg::Vec3d point,double radius) {// 使…

element-ui自定义主题

此处的element-ui为基于vue2.x的 由于https://element.eleme.cn/#/zh-CN/theme/preview&#xff08;element的主题&#xff09;报错503&#xff0c; 所以使用https://element.eleme.cn/#/zh-CN/component/custom-theme 自定义主题文档中&#xff0c;在项目中改变scss变量的方…

windows下使用nginx + waitress 部署django

架构介绍 linux一般采用nginx uwsgi部署django&#xff0c;在Windows下&#xff0c;可以取代uwsgi的选项包括Waitressa、Daphnea、Hypercoma和Gunicorna(通过WSLa 运行)。windows服务器一般采用nginx waitress 部署django&#xff0c;,他们的关系如下 django是WEB应用…

MySQL-多版本并发控制MVCC

文章目录 一、多版本并发控制MVCC二、undo log&#xff08;回滚日志&#xff09;二、已提交读三、可重复读总结 一、多版本并发控制MVCC MVCC是多版本并发控制&#xff08;Multi-Version Concurrency Control&#xff09;&#xff0c;是MySQL中基于乐观锁理论实现隔离级别的方…

目标检测与分割:深度学习在视觉中的应用

&#x1f50d; PART 1&#xff1a;目标检测&#xff08;Object Detection&#xff09; 1️⃣ 什么是目标检测&#xff1f; 目标检测是计算机视觉中的一个任务&#xff0c;目标是让模型“在图像中找到物体”&#xff0c;并且判断&#xff1a; 它是什么类别&#xff08;classif…

杰弗里·辛顿:深度学习教父

名人说&#xff1a;路漫漫其修远兮&#xff0c;吾将上下而求索。—— 屈原《离骚》 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 杰弗里辛顿&#xff1a;当坚持遇见突破&#xff0c;AI迎来新纪元 一、人物简介 杰弗…

STM32蓝牙连接Android实现云端数据通信(电机控制-开源)

引言 基于 STM32F103C8T6 最小系统板完成电机控制。这个小项目采用 HAL 库方法实现&#xff0c;通过 CubeMAX 配置相关引脚&#xff0c;步进电机使用 28BYJ-48 &#xff08;四相五线式步进电机&#xff09;&#xff0c;程序通过蓝牙连接手机 APP 端进行数据收发&#xff0c; OL…

第一个Qt开发的OpenCV程序

OpenCV计算机视觉开发实践&#xff1a;基于Qt C - 商品搜索 - 京东 下载安装Qt&#xff1a;https://download.qt.io/archive/qt/5.14/5.14.2/qt-opensource-windows-x86-5.14.2.exe 下载安装OpenCV&#xff1a;https://opencv.org/releases/ 下载安装CMake&#xff1a;Downl…

TCP 如何在网络 “江湖” 立威建交?

一、特点&#xff1a; &#xff08;一&#xff09;面向连接 在进行数据传输之前&#xff0c;TCP 需要在发送方和接收方之间建立一条逻辑连接。这一过程类似于打电话&#xff0c;双方在通话前需要先拨号建立连接。建立连接的过程通过三次握手来完成&#xff0c;确保通信双方都…

【小白训练日记——2025/4/15】

变化检测常用的性能指标 变化检测&#xff08;Change Detection&#xff09;的性能评估依赖于多种指标&#xff0c;每种指标从不同角度衡量模型的准确性。以下是常用的性能指标及其含义&#xff1a; 1. 混淆矩阵&#xff08;Confusion Matrix&#xff09; 定义&#xff1a;统…

数据结构——二叉树(中)

接上一篇&#xff0c;上一篇主要讲解了关于二叉树的基本知识&#xff0c;也是为了接下来讲解关于堆结构和链式二叉树结构打基础&#xff0c;其实无论是堆结构还是链式二叉树结构&#xff0c;都是二叉树的存储结构&#xff0c;那么今天这一篇主要讲解关于堆结构的实现与应用 堆…

02-MySQL 面试题-mk

文章目录 1.mysql 有哪些存储引擎、区别是什么?1.如何定位慢查询?2.SQL语句执行很慢,如何分析?3.索引概念以及索引底层的数据结构4.什么是聚簇索引什么是非聚簇索引?5.知道什么叫覆盖索引嘛 ?6.索引创建原则有哪些?7.什么情况下索引会失效 ?8.谈一谈你对sql的优化的经验…