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

Netty从0到1系列之Netty整体架构、入门程序

文章目录

  • 一、Netty概述
    • 1.1 官网资料
    • 1.2 概述
    • 1.3 为什么选择Netty?
  • 二、Netty的I/O模型
    • 2.1 I/O模型的核心思想
    • 2.2 Netty 的 I/O 模型演进:三种 Reactor 模式
      • 2.2.1 单 Reactor 单线程模型(Simple)
      • 2.2.2 单 Reactor 多线程模型(Moderate)
      • 2.2.3 主从 Reactor 多线程模型(Recommended)✅
    • 2.3 Netty I/O 模型的底层优化
    • 2.4 I/O 模型对比总结
    • 2.5 Netty I/O 模型的核心价值
    • 2.6 📕一句话总结
  • 三、Netty整体架构解析
    • 3.1 整体架构
    • 3.2 架构设计
      • 3.2.1 Netty架构全景图
      • 3.2.2 Netty的分层架构设计
    • 3.3 Netty架构设计精髓总结
    • 3.4 Netty架构的优缺点分析
    • 3.5 Netty架构设计的核心价值
    • 3.6 一句话总结
  • 四、Netty开发环境搭建
    • 4.1 引入依赖
    • 4.2 配置logback.xml文件
  • 五、入门程序
    • 5.1 服务器端
    • 5.2 客户端
    • 5.3 程序解析

  • 先建立整体认知,不必追求细节.
  • 先建立整体认知,不必追求细节.
  • 先建立整体认知,不必追求细节.

一、Netty概述

1.1 官网资料

https://netty.io/

Netty: Home

Netty 是一个异步事件驱动的网络应用框架
用于快速开发可维护的高性能协议服务器和客户端。

1.2 概述

Netty 是一个 NIO 客户端服务器框架,可以快速轻松地开发网络应用程序,例如协议服务器和客户端。它极大地简化和简化了网络编程,例如 TCP 和 UDP 套接字服务器。

“快速简单”并不意味着生成的应用程序将受到可维护性或性能问题的影响。Netty 是根据从许多协议(如 FTP、SMTP、HTTP 以及各种基于二进制和文本的遗留协议)的实施中获得的经验精心设计的。因此,Netty 成功地找到了一种方法,可以在不妥协的情况下实现开发的便利性、性能、稳定性和灵活性。

在这里插入图片描述

1.3 为什么选择Netty?

Netty 是一个基于 Java NIO 的 异步事件驱动 的高性能网络应用框架,广泛应用于构建高并发、低延迟的协议服务器与客户端,如 RPC 框架(Dubbo、gRPC)、消息中间件(RocketMQ)、即时通讯系统等。

❌ 原生 NIO 编程的复杂性

问题说明
API 复杂需手动管理 SelectorChannelBuffer 状态
空轮询 BugJDK NIO 存在 select() 无限返回 0 的问题
内存管理困难Buffer 分配、释放、泄漏风险高
编解码复杂协议解析需手动实现粘包/拆包
线程模型复杂Reactor 模式需自行实现

🎯 Netty 的目标:简化网络编程,屏蔽底层复杂性,提供高性能、高可扩展性的 API

Netty 核心优势
高性能
高并发
高可扩展
易用性
社区生态
零拷贝支持
内存池
无锁串行化
Reactor 线程模型
支持百万级连接
ChannelHandler 管道
支持多种协议
API 简洁
编解码器丰富
活跃社区
被主流框架采用

✅ 优点

优点说明
高性能无锁串行化、内存池、零拷贝
高并发支持数十万甚至百万连接
高可扩展ChannelHandler 管道模式,易于扩展
API 简洁封装了 NIO 复杂性
协议丰富支持 HTTP、WebSocket、SSL/TLS 等
社区活跃文档齐全,问题易解决
被广泛采用Dubbo、RocketMQ、Elasticsearch 等

二、Netty的I/O模型

2.1 I/O模型的核心思想

✅ 核心目标

  • 单线程处理多个连接(高并发)
  • 无阻塞 I/O 操作(低延迟)
  • 事件驱动处理(高响应性)
  • 避免锁竞争(高性能)

🎯 设计哲学

“让一个线程负责一个事件循环,避免上下文切换和锁开销。”

2.2 Netty 的 I/O 模型演进:三种 Reactor 模式

Netty 支持三种经典的 Reactor 模型,可通过配置灵活切换。

2.2.1 单 Reactor 单线程模型(Simple)

单线程
accept
read/write
handle
Channel
Main Reactor
  • 特点:
    • 所有操作(连接、读、写、业务)由同一个线程完成
    • 适合低并发、调试场景
EventLoopGroup group = new NioEventLoopGroup(1);
bootstrap.group(group) // 单线程

⚠️ 不推荐用于生产环境:业务处理阻塞会拖慢整个 I/O 线程。

2.2.2 单 Reactor 多线程模型(Moderate)

accept
Main Reactor Thread
Client Channel
Sub Reactor Group
Worker Thread-1
Worker Thread-2
Worker Thread-N
Handle I/O + 业务
  • 特点

    • Main Reactor:专门处理 accept 新连接
    • Sub Reactor:多个线程处理 I/O 读写
    • 业务逻辑仍在 I/O 线程中执行
  • 适用场景:中等并发,业务处理轻量

⚠️ 风险:若业务处理耗时,仍会阻塞 I/O 线程。

2.2.3 主从 Reactor 多线程模型(Recommended)✅

accept
Boss Group
New Connection
Worker Group
EventLoop-1
EventLoop-2
EventLoop-N
Handle I/O Events
Business Thread Pool
Execute Business Logic
  • 特点:

    • Boss Group:1 个或少量线程,只负责接收连接
    • Worker Group:多个线程,只负责 I/O 读写
    • 业务处理通过 ctx.executor().execute() 提交到独立的业务线程池
  • 优势:

    • I/O 线程永不阻塞
    • 最大化吞吐量
    • 生产环境推荐模式

2.3 Netty I/O 模型的底层优化

✅ 1. 修复 JDK NIO 空轮询 Bug

  • JDK NIO 存在 select() 无限返回 0 的问题
  • Netty 通过 计数检测 + 重建 Selector 修复

✅ 2. 无锁串行化设计

  • 每个 Channel 绑定到固定 EventLoop
  • 所有操作由同一线程执行,无需加锁

✅ 3. 任务调度优化

  • taskQueue:普通任务(如 channel.write()
  • scheduledTaskQueue:定时任务(如心跳)
  • 避免 ScheduledExecutorService 的锁竞争

2.4 I/O 模型对比总结

模型优点缺点适用场景
单 Reactor 单线程简单、无锁并发低、易阻塞学习、调试
单 Reactor 多线程并发提升业务阻塞 I/O 线程中低并发
主从 Reactor 多线程高并发、高吞吐稍复杂生产环境推荐

2.5 Netty I/O 模型的核心价值

维度说明
核心模式主从 Reactor 多线程模型
关键优势异步、非阻塞、无锁、高并发
性能保障事件循环 + 任务队列 + 内存池
设计精髓“一个线程一个事件循环”
适用场景高性能 RPC、网关、消息系统

2.6 📕一句话总结

💡 一句话总结

Netty 的 I/O 模型通过 主从 Reactor 架构无锁串行化设计,实现了 单机百万级并发连接 的能力,是现代高性能网络服务的标准范式

三、Netty整体架构解析

3.1 整体架构

在这里插入图片描述

  • Core层

    • Core 核心层是 Netty 最精华的内容,它提供了底层网络通信的通用抽象和实现,包括可扩展的事件模型、通用的通信 API、支持零拷贝的 ByteBuf 等
  • Protocol Support 协议支持层

    • 协议支持层基本上覆盖了主流协议的编解码实现,如 HTTP、SSL、Protobuf、压缩、大文件传输、WebSocket、文本、二进制等主流协议,此外 Netty 还支持自定义应用层协议。Netty 丰富的协议支持降低了用户的开发成本,基于 Netty 我们可以快速开发 HTTP、WebSocket 等服务。
  • Transport Service 传输服务层

    • 传输服务层提供了网络传输能力的定义和实现方法。它支持 Socket、HTTP 隧道、虚拟机管道等传输方式。Netty 对 TCP、UDP 等数据传输做了抽象和封装,用户可以更聚焦在业务逻辑实现上,而不必关系底层数据传输的细节。

      Netty 的模块设计具备较高的通用性和可扩展性,它不仅是一个优秀的网络框架,还可以作为网络编程的工具箱。Netty 的设计理念非常优雅,值得我们学习借鉴。

3.2 架构设计

Netty 不仅仅是一个网络通信库,它是一个高度模块化、可扩展、高性能的异步事件驱动网络应用框架。其架构设计融合了多种经典设计模式与系统优化思想,是现代高性能网络编程的典范。

本文将从 分层架构、核心组件、数据流、线程模型、扩展机制 五个维度,全面深入剖析 Netty 的整体架构设计。

3.2.1 Netty架构全景图

Utility
CodecAndProtocol
TransportLayer
CoreFramework
ApplicationLayer
内存池
Future/Promise
Bootstrap
编解码器
HTTP
WebSocket
Protobuf
NIO
OIO
Epoll
UDT
ChannelPipeline
Channel
Unsafe
ByteBuf
EventLoop
EventLoopGroup
Thread
ChannelHandler
业务逻辑

3.2.2 Netty的分层架构设计

Netty 采用清晰的 分层架构,各层职责分明,耦合度低。

1. 应用层(Application Layer)

  • 职责:实现具体业务逻辑
  • 组件ChannelHandlerChannelInboundHandlerChannelOutboundHandler

  • 特点:开发者主要编写代码的层级

2. 核心框架层(Core Framework)

  • 职责:事件调度、I/O 处理、线程管理
  • 组件
    • ChannelPipeline:事件处理管道
    • Channel:网络连接抽象
    • EventLoop:事件循环
    • EventLoopGroup:线程组
    • ByteBuf:内存管理

3. 传输层(Transport Layer)

  • 职责:提供多种 I/O 模型支持
  • 实现
    • NIO:基于 JDK NIO(NioEventLoopGroup
    • Epoll:Linux 专属高性能(EpollEventLoopGroup
    • OIO:阻塞 I/O(已不推荐)
    • UDT:UDP-based Data Transfer

4. 协议编解码层(Codec & Protocol)

  • 职责:协议解析与生成
  • 组件
    • ByteToMessageDecoder:字节流 → 消息对象
    • MessageToByteEncoder:消息对象 → 字节流
    • 内置编解码器:LengthFieldBasedFrameDecoderStringEncoder
    • 协议支持:HTTP、WebSocket、SSL/TLS、Protobuf

5. 工具层(Utility Layer)

  • 职责:提供通用能力
  • 组件
    • ByteBufAllocator:内存分配器(支持池化)
    • Future / Promise:异步结果通知
    • Bootstrap / ServerBootstrap:启动辅助类
    • ReferenceCountUtil:引用计数工具

3.3 Netty架构设计精髓总结

设计原则说明实现方式
单一职责每个组件只做一件事ChannelPipelineEventLoop 分离
开闭原则对扩展开放,对修改关闭ChannelHandler 管道模式
依赖倒置高层依赖抽象Channel 接口,多种实现(NIO/Epoll)
无锁设计避免锁竞争无锁串行化 + EventLoop 绑定 Channel
异步非阻塞高并发基础Future/Promise + 事件驱动
资源复用减少 GC内存池、对象池

3.4 Netty架构的优缺点分析

✅ 优点

优点说明
高性能无锁串行化、内存池、零拷贝
高可扩展ChannelHandler 可插拔
高可靠性成熟稳定,被主流框架广泛采用
协议丰富内置 HTTP、WebSocket、SSL 等
跨平台支持 NIO(通用)、Epoll(Linux 优化)
易测试EmbeddedChannel 支持单元测试

❌ 缺点

缺点说明
学习成本高Reactor 模型、事件驱动需理解
内存管理复杂ByteBuf 需手动释放,易泄漏
调试困难异步堆栈不直观
过度设计简单场景可能不必要

3.5 Netty架构设计的核心价值

Netty 的架构设计是“简单、高效、可扩展”哲学的完美体现。

维度说明
核心思想异步事件驱动 + 无锁串行化 + 责任链模式
关键技术Reactor 模型、内存池、零拷贝、引用计数
设计目标单机百万连接、微秒级延迟、高吞吐量
行业地位Java 高性能网络编程的事实标准
适用场景RPC、网关、消息系统、游戏服务器、物联网

3.6 一句话总结

💡 一句话总结

Netty 通过 分层架构组件化设计极致优化,构建了一个高性能、高可靠、高可扩展的网络通信平台,是现代分布式系统不可或缺的基础设施。

四、Netty开发环境搭建

4.1 引入依赖

<properties><maven.compiler.source>24</maven.compiler.source><maven.compiler.target>24</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties><dependencies><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.5.18</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>2.0.16</version></dependency><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-core</artifactId><version>1.5.18</version></dependency><!-- https://mvnrepository.com/artifact/io.netty/netty-all --><dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.1.112.Final</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.38</version></dependency>
</dependencies>

4.2 配置logback.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<configurationxmlns="http://ch.qos.logback/xml/ns/logback"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://ch.qos.logback/xml/ns/logback logback.xsd"><!-- 输出控制,格式控制--><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%date{HH:mm:ss} [%-5level] [%thread] %logger{17} - %m%n </pattern></encoder></appender><!-- 用来控制查看那个类的日志内容(对mybatis name 代表命名空间) --><logger name="cn.tcmeta" level="DEBUG" additivity="false"><appender-ref ref="STDOUT"/></logger><logger name="io.netty.handler.logging.LoggingHandler" level="DEBUG" additivity="false"><appender-ref ref="STDOUT"/></logger><root level="ERROR"><appender-ref ref="STDOUT"/></root>
</configuration>

五、入门程序

5.1 服务器端

package cn.tcmeta.demo01;import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import lombok.extern.slf4j.Slf4j;/*** @author: laoren* @description: Netty入门案例* @version: 1.0.0*/
@Slf4j
public class NettyServerDemo01 {public static void main(String[] args) {// 1. 创建服务器new ServerBootstrap()// 2. 创建NioEventLoopGroup, 现在可以简单理解为: 线程池 + Selector.// BossEventLoop, WorkerEventLoop(select, thread).group(new NioEventLoopGroup())// 3. 选择服务Socket实现类, 其中NioServerSocketChannel, 表示NIO的服务器端实现..channel(NioServerSocketChannel.class)// 4. 接下来添加的处理器都是给SocketChannel用的, 而不是给ServetSocketChannel用的.// ChannelInitializer处理器(仅执行一次),它的作用是待客户端SocketChannel建立连接后, 执行// initChannel以便添加更多的处理器.// boss处理连接, child(worker)进行读写操作.所以这里child添加的是处理SocketChannel的主要逻辑.// 执行操作封装为handler(处理器).childHandler(new ChannelInitializer<NioSocketChannel>() {// 5. 执行添加处理器@Overrideprotected void initChannel(NioSocketChannel ch) throws Exception { // ChannelInitializer, 初始化channel, 添加各种各样的handler// 7. 处理SocketChannel, 解码 ByteBuf ---> Stringch.pipeline().addLast(new StringDecoder());// 8. 处理SocketChannel业务处理器, 使用上一个处理器的处理结果.ch.pipeline().addLast(new SimpleChannelInboundHandler<String>() {@Overrideprotected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {System.out.println(msg);}});}// 6. 绑定服务器端口号}).bind(8888);log.debug("服务器已经启动, 监听端口号为 8888 ................");}
}

5.2 客户端

package cn.tcmeta.demo01;import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringEncoder;import java.util.Date;/*** @author: laoren* @description: 客户端测试* @version: 1.0.0*/
public class ClientDemo01 {public static void main(String[] args) throws InterruptedException {new Bootstrap()// 创建NioEventLoopGroup, 可以理解为线程池 + Selector.group(new NioEventLoopGroup())// 2..channel(NioSocketChannel.class).handler(new ChannelInitializer<Channel>() {@Overrideprotected void initChannel(Channel ch) throws Exception {ch.pipeline().addLast(new StringEncoder()); // 设置编码器}}).connect("127.0.0.1", 8888).sync().channel()// 向服务器发送数据.writeAndFlush(new Date() + ", hello netty!");}
}

服务器输出日志

在这里插入图片描述

5.3 程序解析

  • channel可以理解为数据传输的通道.
  • msg理解为流动的数据, 原始数据是ByteBuf, 经过pipeline的加工, 会将其变成类型对象, 最后输出又变成ByteBuf对象.
  • handler理解为数据处理的工序
    • 工序有多道,合在一起就构成了pipeline, pipeline负责发布事件【读、取完成等】传播每个handler, handler对自己感兴趣的事件进行处理【重写相应事件处理的方法】
    • handler分为InboundOutBound两类.
  • eventLoop理解为处理数据的工人
    • 工人可以同时管理多个channelio操作,并且一旦工作负责了某个channel,就要负责到底【绑定】
    • 工人既可以执行 io 操作,也可以进行任务处理,每位工人有任务队列,队列里可以堆放多个 channel 的待处理任务,任务分为普通任务、定时任务
    • 工人按照 pipeline 顺序,依次按照 handler 的规划(代码)处理数据,可以为每道工序指定不同的工人

文章转载自:

http://s5hACAr1.dkcqs.cn
http://Zj6qPwA7.dkcqs.cn
http://W2W7jsFu.dkcqs.cn
http://zX1fkNp5.dkcqs.cn
http://XkvseRQq.dkcqs.cn
http://Fg2hhNrI.dkcqs.cn
http://QwGYDw5h.dkcqs.cn
http://kmWgHYYJ.dkcqs.cn
http://fVvRZksT.dkcqs.cn
http://inZrRKC2.dkcqs.cn
http://yL2V3k9A.dkcqs.cn
http://K8fl2oiU.dkcqs.cn
http://CmiAaGo7.dkcqs.cn
http://95QQVq7J.dkcqs.cn
http://9LvUd7JE.dkcqs.cn
http://8gdJBxYV.dkcqs.cn
http://dKPEdj2B.dkcqs.cn
http://d6BLEvlM.dkcqs.cn
http://S18qEAlY.dkcqs.cn
http://GFYInDCs.dkcqs.cn
http://MRf0fmNc.dkcqs.cn
http://ve8d20BO.dkcqs.cn
http://81miGxpe.dkcqs.cn
http://rGTZz9mW.dkcqs.cn
http://IsohKwF7.dkcqs.cn
http://8VTmNF98.dkcqs.cn
http://N92wtul5.dkcqs.cn
http://ijQJ1HkC.dkcqs.cn
http://e4sDI5rN.dkcqs.cn
http://5CROL0yG.dkcqs.cn
http://www.dtcms.com/a/368087.html

相关文章:

  • 实战记录:H3C路由器IS-IS Level-1邻居建立与路由发布
  • iOS 抓包工具有哪些?常见问题与对应解决方案
  • 【Linux】网络安全管理:SELinux 和 防火墙联合使用 | Redhat
  • Boost搜索引擎 网络库与前端(4)
  • 服务器硬盘“Unconfigured Bad“状态解决方案
  • 警惕!你和ChatGPT的对话,可能正在制造分布式妄想
  • 中天互联:AI 重塑制造,解锁智能生产新效能​
  • 如何制造一个AI Agent:从“人工智障”到“人工智能”的奇幻漂流
  • 鼓励员工提出建议,激发参与感——制造企业软件应用升级的密钥
  • 2025世界职校技能大赛总决赛争夺赛汽车制造与维修赛道比赛资讯
  • LeetCode 240: 搜索二维矩阵 II - 算法详解(秒懂系列
  • [特殊字符] AI时代依然不可或缺:精通后端开发的10个GitHub宝藏仓库
  • 【MFC】对话框节点属性:Condition(条件)
  • 【MFC 小白日记】对话框编辑器里“原型图像”到底要不要勾?3 分钟看懂!
  • 【为YOLOv11Seg添加MFC界面】详细指南
  • VBA 中使用 ADODB 操作 SQLite 插入中文乱码问题
  • Python 实现 Markdown 与 Word 高保真互转(含批量转换)
  • 如何在 C# 中将文本转换为 Word 以及将 Word 转换为文本
  • 电商企业如何选择高性价比仓储系统?专业定制+独立部署,源码交付无忧
  • Mysql:由逗号分隔的id组成的varchar联表替换成对应文字
  • Windows环境下实现GitLab与Gitee仓库代码提交隔离
  • PXM的JAVA并发编程学习总结
  • Cursor Pair Programming:在前端项目里用 AI 快速迭代 UI 组件
  • java面试中经常会问到的集合问题有哪些(基础版)
  • 23种设计模式——桥接模式 (Bridge Pattern)详解
  • AI日报 - 2025年09月05日
  • 23ai数据库通过SQLcl生成AWR报告
  • 销量骤降、降价自救,新别克GL8能否成为上汽通用救星?
  • 如何解决 OutOfMemoryError 内存溢出 —— 原因、定位与解决方案
  • Kubernetes实战系列(4)