Netty 详细讲解
目录一、BIO / NIO / AIO 简单对比Java NIO 三大组件二、Netty 核心架构与线程模型重中之重主从 Reactor 模型NioEventLoop三、Channel、Pipeline、ChannelHandler核心三件套1. Channel2. ChannelPipeline 流水线3. ChannelHandler 处理器ByteBufNetty 封装的缓冲区替代 JDK ByteBuffer四、编解码器解决粘包半包五、Netty 重要概念1. ChannelFuture2. ChannelOption / ChildOption3. IdleStateHandler 空闲检测业务心跳4. 零拷贝 Zero‑Copy六、Netty 执行完整流程服务端接收消息全过程七、常见坑面试高频八、Netty 的 Reactor 面试高频问题九、简单完整示例服务端十、Netty 适合什么场景Netty 是基于 Java NIO 的高性能、异步事件驱动的网络通信框架封装了 Java 原生 NIO 的复杂 API用于快速开发高并发的 TCP/UDP 网络服务端、客户端。主流中间件底层网络全部用 NettyRocketMQ、Dubbo、Elasticsearch、Zookeeper、Spring Cloud Gateway、Redis Java 客户端。Java 网络演进BIO → NIO(Java原生) → Netty(封装NIO)一、BIO / NIO / AIO 简单对比模型IO 类型线程模型缺点BIO阻塞 IO1 连接 1 线程高并发下线程爆炸上下文切换重NIO(Java)非阻塞同步单线程 Selector 轮询原生 API 繁琐BUG 多 (空轮询 bug)AIO异步非阻塞操作系统回调Windows 好Linux 内核支持差实际很少用Netty 底层在 Linux 上使用 NIOEpollWindows 上会自动切换 AIO。生产环境几乎都是 NIO 模式。Java NIO 三大组件Buffer 缓冲区数据读写容器ByteBufferChannel 通道双向读写SocketChannel、ServerSocketChannelSelector 选择器多路复用器一个线程监听大量 Channel 事件连接、读、写实现少量线程处理上万连接。原生 NIO 痛点ByteBuffer API 难用需要 flip、rewind、clear容易内存溢出Selector 空轮询 BUG (JDK bug)CPU 100%没有编解码器、断连处理、心跳、半包粘包全部自己手写线程模型、异常处理需要自己实现 Netty 就是把这些坑全部封装好。二、Netty 核心架构与线程模型重中之重Netty 核心线程模型Reactor 反应器模式Netty 实现了三种 Reactor单线程 Reactor不生产用一个线程干接受连接 处理 IO多线程 Reactor一个 accept 线程N 个 IO 线程处理读写主从 ReactorNetty 默认【生产常用】主从 Reactor 模型Boss Group主 Reactor负责接收 TCP 连接只做 accept不处理业务读写。一般 1 个线程足够。Worker Group从 Reactor处理已建立连接的所有 IO 事件read、write、编解码、触发 handlerN 个线程。NioEventLoopGroup 就是线程组NioEventLoop 就是单个线程。java// 服务端经典初始化代码 // boss线程组接收连接worker线程组处理socket读写 NioEventLoopGroup bossGroup new NioEventLoopGroup(1); NioEventLoopGroup workerGroup new NioEventLoopGroup(); ServerBootstrap bootstrap new ServerBootstrap(); bootstrap.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) // 指定NIO通道实现 .option(ChannelOption.SO_BACKLOG,128) // tcp半连接队列 .childOption(ChannelOption.SO_KEEPALIVE,true) // tcp心跳 .childHandler(new ChannelInitializerNioSocketChannel() { Override protected void initChannel(NioSocketChannel ch) { // 流水线添加处理器 ch.pipeline().addLast(new MyHandler()); } }); ChannelFuture future bootstrap.bind(8888).sync(); future.channel().closeFuture().sync();NioEventLoop一个NioEventLoop对应一个 Java 线程 一个 Selector一个 Worker NioEventLoop 可以绑定多个 SocketChannel多路复用监听 IO 事件一个 SocketChannel 永远只会绑定到同一个 NioEventLoop 线程所以同一个 channel 的 handler 执行是单线程不需要同步锁非常关键的特性任务队列每个 NioEventLoop 有任务队列支持普通任务、定时任务。注意不要在 Netty IO 线程执行耗时业务数据库查询、http 调用会阻塞整个线程所有绑定这个线程的连接全部卡死 耗时业务丢到自定义业务线程池执行。三、Channel、Pipeline、ChannelHandler核心三件套1. Channel代表一条 Socket 连接封装底层 Java NIO SocketChannel。 常用方法writeAndFlush()写消息并刷到内核缓冲区close()关闭连接channel().isActive()判断连接是否存活2. ChannelPipeline 流水线每个 Channel 内部持有一个ChannelPipeline是Handler 的双向链表。 IO 事件会沿着 pipeline 依次流转。inbound 入站事件外部 → 服务端连接建立、读数据从 head→tail 执行 outbound 出站事件服务端 → 外部写数据、关闭从 tail→head 执行HeadContext -- Handler1 -- Handler2 -- TailContext3. ChannelHandler 处理器分为两类ChannelInboundHandler 入站处理器处理接收过来的数据channelRead()读取报文ChannelOutboundHandler 出站处理器处理向外发送的数据write()常用适配器简化开发ChannelInboundHandlerAdapterChannelOutboundHandlerAdapterSimpleChannelInboundHandler自动释放 ByteBuf泛型直接拿到解码后的对象业务 handler 最常用ByteBufNetty 封装的缓冲区替代 JDK ByteBufferNetty 自己实现的缓冲区解决原生 ByteBuffer 的痛点读写指针分离readerIndex、writerIndex不用 flip 切换支持池化内存PooledByteBuf默认开启复用直接内存减少 GC支持复合缓冲区 CompositeByteBuf组合多个缓冲区不拷贝堆内存 (HeapByteBuf) / 直接内存 (DirectByteBuf零拷贝不走 JVM 堆)⚠️内存释放Netty 引用计数retain()/release()DirectByteBuf 不释放会直接内存泄漏 SimpleChannelInboundHandler 会自动 release普通 InboundHandler 拿到 ByteBuf处理完必须手动 release。四、编解码器解决粘包半包TCP 是流协议没有消息边界会出现粘包、半包多条报文粘在一起或者一条报文被拆成多次到达。Netty 内置开箱即用解码器FixedLengthFrameDecoder固定长度帧DelimiterBasedFrameDecoder分隔符分割报文比如换行符LengthFieldBasedFrameDecoder【最常用】长度域解码器协议头部存消息长度支持自定义偏移RPC、MQ 大量使用。解码器属于 InboundHandler编码器属于 OutboundHandler。 编码业务对象 → ByteBuf解码ByteBuf → 业务对象。示例Protobuf、JSON 都可以配合 LengthFieldBasedFrameDecoder 做私有二进制协议。五、Netty 重要概念1. ChannelFutureNetty 所有 IO 操作全是异步bind、connect、writeAndFlush 全部返回 ChannelFuture不会阻塞。.sync()阻塞等待操作完成.addListener()异步回调推荐不阻塞线程java// 异步回调写法 channel.writeAndFlush(msg).addListener(future - { if(future.isSuccess()){ System.out.println(发送成功); }else{ future.cause().printStackTrace(); } });2. ChannelOption / ChildOptionOption作用于服务端 ServerSocketChannel接受连接的那个 socketChildOption作用于每一条客户端 SocketChannel常用参数SO_BACKLOGTCP 半连接队列大小SO_KEEPALIVETCP 层面的空闲探测不推荐业务心跳粒度粗TCP_NODELAY关闭 Nagle 算法小报文立刻发送低延迟系统开启3. IdleStateHandler 空闲检测业务心跳TCP keepalive 是内核层业务感知差。Netty 提供空闲处理器放在 pipeline检测读空闲、写空闲触发事件我们发送心跳包超时关闭僵死连接。java// 读空闲5秒写空闲8秒读写空闲10秒触发IdleStateEvent ch.pipeline().addLast(new IdleStateHandler(5,8,10));4. 零拷贝 Zero‑CopyNetty 的零拷贝不是操作系统 mmap 那种分几层FileRegion文件传输直接把文件从磁盘发送到网卡不拷贝到 JVM 内存CompositeByteBuf逻辑合并多个缓冲区不做内存复制Direct Buffer使用操作系统直接内存JVM 堆和 socket 之间少一次拷贝六、Netty 执行完整流程服务端接收消息全过程BossGroup NioEventLoop 的 Selector 监听 OP_ACCEPT 事件有客户端连接进来accept 得到 SocketChannel将 SocketChannel 注册到 WorkerGroup 其中一个 NioEventLoop 的 Selector 上监听 OP_READ 事件客户端发送数据Worker 线程 Selector 触发 OP_READ读到字节到 ByteBuf进入 pipeline从 head 开始执行各个 InboundHandler首先经过解码器LengthFieldBasedFrameDecoder拆包把 ByteBuf 转成业务 POJO 对象执行业务 Handler channelRead () 方法如果业务要返回响应调用 writeAndFlush事件反向走 OutboundHandler编码器编码最终发送到 socket 缓冲区write () 只是写入缓冲区不会真正发送必须调用 flush 才会刷出writeAndFlush 合并两个操作。七、常见坑面试高频禁止在 IO 线程执行耗时操作数据库、RPC、复杂计算会阻塞 NioEventLoop 线程同线程所有连接卡死。解决方案把任务提交到自定义业务线程池。DirectByteBuf 内存泄漏直接内存不在堆GC 不会自动回收必须 release开启-Dio.netty.leakDetection.levelPARANOID检测内存泄漏。粘包半包不要裸用 ByteBuf 接收业务报文必须加解码器。不要混用同步 sync ()IO 线程内调用 sync () 造成死锁IO 线程中绝对不能调用 future.sync ()要用 addListener 异步回调。NioEventLoop 绑定 Channel 后channel 所有 handler 都在这个线程执行所以同一个 channel 内变量不需要加 synchronized跨多个 channel 共享变量仍然需要锁。TCP 断开不一定触发 channelRead一定要捕获channelInactive连接断开事件清理会话。八、Netty 的 Reactor 面试高频问题QBossGroup 线程数为什么一般设置 1 ServerSocketChannel 只有一个只负责 accept 接受连接单线程足够多线程反而会竞争 accept 锁没有收益。QWorkerGroup 默认线程数CPU核心数*2Netty 默认构造器就是这个值。QNetty 怎么解决 JDK NIO Selector 空轮询 bug 检测 Selector.select () 返回 0 但没有 IO 事件达到阈值就重建新 Selector把所有 channel 迁移过去。QwriteAndFlush 发送消息是立刻发送给客户端吗 不是写到 Netty 的发送缓冲区队列由 NioEventLoop 在合适时机调用底层 socket write 系统调用刷入操作系统内核 socket 缓冲区内核缓冲区再发给网络。九、简单完整示例服务端javapublic class NettyServerDemo { public static void main(String[] args) throws InterruptedException { NioEventLoopGroup boss new NioEventLoopGroup(1); NioEventLoopGroup worker new NioEventLoopGroup(); try { ServerBootstrap b new ServerBootstrap(); b.group(boss, worker) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializerNioSocketChannel() { Override protected void initChannel(NioSocketChannel ch) { ChannelPipeline p ch.pipeline(); // 简单按换行符分割报文 p.addLast(new DelimiterBasedFrameDecoder(1024, Delimiters.lineDelimiter())); p.addLast(new StringDecoder()); p.addLast(new StringEncoder()); // 业务handler p.addLast(new SimpleChannelInboundHandlerString() { Override protected void channelRead0(ChannelHandlerContext ctx, String msg) { System.out.println(收到客户端消息 msg); ctx.writeAndFlush(服务端回执 msg \r\n); } Override public void channelInactive(ChannelHandlerContext ctx) { System.out.println(客户端断开连接); } }); } }); ChannelFuture f b.bind(9000).sync(); f.channel().closeFuture().sync(); } finally { boss.shutdownGracefully(); worker.shutdownGracefully(); } } }十、Netty 适合什么场景✅ 长连接服务、RPC 框架、消息中间件、网关、IM 聊天、私有二进制协议 ❌ 简单短连接 http 接口直接用 SpringBoot web 即可没必要手写 Netty如果你需要我可以继续手写 Netty 客户端完整代码LengthFieldBasedFrameDecoder 详细图解协议头长度域模拟半包粘包演示Netty 高频面试题整理Netty 源码核心流程梳理NioEventLoop.run 循环

相关新闻

Apex第30赛季启动报错全解决:Easy Anti-Cheat弹窗、运行库缺失、ACE冲突一次搞定

Apex第30赛季启动报错全解决:Easy Anti-Cheat弹窗、运行库缺失、ACE冲突一次搞定

前言最近《Apex Legends》第30赛季已经正式更新,按理说新赛季应该带来更好的游戏体验,但我在社区逛了一圈发现,还是有大量玩家反映启动游戏时弹出Easy Anti-Cheat报错、运行库缺失提示以及各类不明弹窗,导致游戏根本无法启动。本文…

2026/10/18 19:54:56 阅读更多 →
编程基础:分支与循环结构详解与应用实践

编程基础:分支与循环结构详解与应用实践

1. 编程基础中的分支与循环结构解析 在编程的世界里,分支和循环就像是我们日常决策与重复工作的数字化映射。作为程序控制流的两大基石,它们构成了几乎所有复杂算法的骨架。记得我第一次学习编程时,老师用"十字路口的红绿灯"比喻分…

2026/10/17 22:52:17 阅读更多 →
AI Agent:不是只会聊天的百科,而是能动手办事的AI助手,程序员必学的核心能力!

AI Agent:不是只会聊天的百科,而是能动手办事的AI助手,程序员必学的核心能力!

🍔如果用一句话解释:AI Agent(智能体)就是能主动思考、会使用工具、可独立完成复杂任务的智能员工 . Agent AI大模型(大脑) 工具(手脚) 自主行动(执行力) …

2026/10/16 14:19:43 阅读更多 →

最新新闻

基于YOLO与PySide6的交通信号标志识别软件实战解析

基于YOLO与PySide6的交通信号标志识别软件实战解析

我做这个项目之前,其实是被一个很小的场景触动到的:开车经过路口时,导航播报和旁边实际挂着的限速牌经常对不上。路牌就摆在那,但我不能一直分心去辨认,于是萌生了自己写一个交通信号标志识别软件的想法。项目最终落地…

2026/10/18 19:54:34 阅读更多 →
rea架构实战:事件驱动与状态分层解决中后台前端通信难题

rea架构实战:事件驱动与状态分层解决中后台前端通信难题

最近我在整理一个内部项目的代码,代号叫 rea。这名字最开始没那么多讲究,就是随手起的项目代号,结果做着做着,团队发现三个字母正好能概括这套架构的核心:Reactive、Event-driven、Architecture。响应式、事件驱动、架…

2026/10/18 19:54:34 阅读更多 →
大模型本地部署实战指南:从硬件选型到性能调优

大模型本地部署实战指南:从硬件选型到性能调优

你有没有遇到过这种时刻:手里的对话式AI突然响应很慢,或者某天早上打开后台发现API额度又超了,而内部数据根本不敢传到别人服务器上。我当时决定把大模型本地部署到自己机器上,倒不是追逐什么技术潮流,纯粹是项目需要—…

2026/10/18 19:54:34 阅读更多 →
从权重转换到推理优化:OpenVINO落地MiniCPM-o-4.5全模态模型

从权重转换到推理优化:OpenVINO落地MiniCPM-o-4.5全模态模型

这几天在本地折腾全模态模型部署,一开始还是按老套路来:先把 PyTorch 权重拉下来,写个 Python 脚本跑通,再慢慢抠显存优化。等到真把 MiniCPM-o-4.5 和 OpenVINO 拼在一起,才发现端侧部署这件事比想象中省心&#xff0…

2026/10/18 19:54:34 阅读更多 →
微信小程序个人日程安排系统毕业设计资源包实战指南

微信小程序个人日程安排系统毕业设计资源包实战指南

简介:面向计算机专业学生,这是一份微信小程序个人日程安排系统的毕业设计完整项目,采用微信小程序开发工具搭配Java后端与MySQL数据库,实现了个人中心、用户管理、重要日管理、工作日程管理、会面管理、用餐管理、日程管理及系统管…

2026/10/18 19:54:34 阅读更多 →
面试宝典:Oracle数据库cursor: pin X等待事件处理过程与TaoToken排查思路

面试宝典:Oracle数据库cursor: pin X等待事件处理过程与TaoToken排查思路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 19:53:33 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →