当前位置: 首页 > article >正文

【Netty篇】EventLoopGroup 与 EventLoop 详解

在这里插入图片描述

目录

    • 开场白:话说 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 核心数 * 2try {ServerBootstrap b = new ServerBootstrap();b.group(bossGroup, workerGroup) // 设置 bossGroup 和 workerGroup.channel(NioServerSocketChannel.class) // 指定使用 NIO 的 ServerSocketChannel.childHandler(new ChannelInitializer<SocketChannel>() { // 设置 ChannelHandler@Overridepublic 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 崩溃。 ⚠️

相关文章:

【Netty篇】EventLoopGroup 与 EventLoop 详解

目录 开场白&#xff1a;话说 Netty 江湖第一段&#xff1a;EventLoopGroup——“包工头”的角色第二段&#xff1a;EventLoop——“身怀绝技的工人”第三段&#xff1a;EventLoop 如何处理 I/O 事件、普通任务和定时任务第四段&#xff1a;Handler 执行中如何换人&#xff1f;…...

操作系统之shell实现(上)

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

考研数据结构之图的遍历:深度优先搜索(DFS)与广度优先搜索(BFS)(包含真题及解析)

考研数据结构之图的遍历&#xff1a;深度优先搜索&#xff08;DFS&#xff09;与广度优先搜索&#xff08;BFS&#xff09; 图的遍历是图论中的核心操作之一&#xff0c;主要包括深度优先搜索&#xff08;DFS&#xff09;和广度优先搜索&#xff08;BFS&#xff09;。本文将详…...

数据结构与算法——链表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…...

MySQL慢SQL优化方案详解:从诊断到根治的完整指南

MySQL慢SQL优化方案详解&#xff1a;从诊断到根治的完整指南 一、慢SQL的致命影响 当数据库响应时间超过500ms时&#xff0c;系统将面临三大灾难链式反应&#xff1a; 用户体验崩塌 页面加载超时率上升37%用户跳出率增加52%核心业务转化率下降29% 系统稳定性危机 连接池耗…...

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) {// 使…...

Ant Design Vue 的表格数据,第一列项目区域,项目区域相同的行数据,第一列项目区域合并

在 Ant Design Vue 的表格中&#xff0c;如果需要根据第一列&#xff08;如“项目区域”&#xff09;的值进行动态合并&#xff0c;可以通过 customCell 方法实现。以下是完整的代码示例&#xff0c;展示如何根据“项目区域”相同的行数据&#xff0c;合并第一列单元格。 代码示…...

SFOS2:常用容器(布局)介绍

一、前言 最近在进行sailfish os的开发&#xff0c;由于在此之前并没有从事过QT开发的工作&#xff0c;所以对这一套颇为生疏&#xff0c;以此记录一下。以下内容不一定完全准确&#xff0c;开发所使用的是Qt Quick 2.6与Sailfish.Silica 1.0两个库。 二、布局 1.Qt Quick 2.…...

C++ 核心进阶

模块九&#xff1a;进一步学习 (指引方向) 目录 标准模板库 (STL) 深入 1.1. std::map (进阶) 1.1.1. 迭代器的更多用法 1.1.2. 自定义比较函数 1.1.3. std::multimap 1.2. std::set (进阶) 1.2.1. 迭代器的更多用法 1.2.2. 自定义比较函数 1.2.3. std::multiset 和 std::un…...

守护进程编程

守护进程编程 1. 守护进程的含义 守护进程的含义&#xff1a; 守护进程&#xff08;Daemon&#xff09;是指一种在后台运行的进程&#xff0c;通常不与用户交互&#xff0c;用于执行一些常驻任务&#xff0c;如系统监控、日志管理、定时任务等。它通常在操作系统启动时就被启…...

[特殊字符] MySQL MCP 开发实战:打造智能数据库操作助手

&#x1f4a1; 简介&#xff1a;本文详细介绍如何利用MCP&#xff08;Model-Control-Panel&#xff09;框架开发MySQL数据库操作工具&#xff0c;使AI助手能够直接执行数据库操作。 &#x1f4da; 目录 引言MCP框架简介项目架构设计开发环境搭建核心代码实现错误处理策略运行和…...

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中基于乐观锁理论实现隔离级别的方…...

Sherpa简介

Sherpa 是一个由 K2-FSA 团队 开发的 开源语音处理框架&#xff0c;旨在解决传统语音识别工具&#xff08;如 Kaldi&#xff09;在模型部署和跨平台适配中的复杂性问题。它通过整合现代深度学习技术和高效推理引擎&#xff0c;提供了从语音识别、合成到说话人识别的一站式解决方…...

4.15redis点评项目下

--->接redis点评项目上 Redis优化秒杀方案 下单流程为&#xff1a;用户请求nginx--->访问tomcat--->查询优惠券--->判断秒杀库存是否足够--->查询订单--->校验是否是一人一单--->扣减库存--->创建订单 以上流程如果要串行执行耗时会很多&#xff0c…...

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

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

SpringBoot 与 Vue3 实现前后端互联全解析

在当前的互联网时代&#xff0c;前后端分离架构已经成为构建高效、可维护且易于扩展应用系统的主流方式。本文将详细介绍如何利用 SpringBoot 与 Vue3 构建一个前后端分离的项目&#xff0c;展示两者如何通过 RESTful API 实现无缝通信&#xff0c;让读者了解从环境搭建、代码实…...

HEIF、HEIC、JPG 和 PNG是什么?

1. HEIF (High Efficiency Image Format) 定义&#xff1a;HEIF 是一种用于存储单张图像和图像序列&#xff08;如连拍照片&#xff09;的图像文件格式。优势&#xff1a;相比传统的图像格式&#xff0c;HEIF 提供了更高的压缩效率和更好的图像质量。压缩算法&#xff1a;HEI…...

第一层、第二层与第三层隧道协议

&#xff08;本文由deepseek生成&#xff0c;特此声明&#xff09; 隧道协议是网络通信中用于在不同网络间安全传输数据的关键技术&#xff0c;其工作层次决定了封装方式、功能特性及应用场景。本文将详细介绍物理层&#xff08;第一层&#xff09;、数据链路层&#xff08;第…...

部署qwen2.5-VL-7B

简单串行执行 from transformers import Qwen2_5_VLForConditionalGeneration, AutoProcessor from qwen_vl_utils import process_vision_info import torch, time, threadingdef llm(model_path,promptNone,imageNone,videoNone,imagesNone,videosNone,max_new_tokens2048,t…...

记录jdk8->jdk17 遇到的坑和解决方案

最近项目在升级jdk8->jdk17 springboot2->springboot3 顺序先升级业务服务&#xff0c;后升级组件服务。跟随迭代开发一起验证功能。 1. 使用parent pom 版本管理 spring相关组件的版本。 组件依赖低版本parent不变。 业务服务依赖高版本parent。 2. 修改maven jdk…...

vue3 uniapp vite 配置之定义指令

动态引入指令 // src/directives/index.js import trim from ./trim;const directives {trim, };export default {install(app) {console.log([✔] 自定义指令插件 install 触发了&#xff01;);Object.entries(directives).forEach(([key, directive]) > {app.directive(…...

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

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