1-Netty基础知识 1-Netty基础知识Netty官网https://netty.io/来自官网对Netty的描述Netty isan asynchronous event-driven network application frameworkfor rapid development of maintainable high performance protocol servers clients.Netty是一个异步事件驱动的网络应用框架用于快速开发可维护的高性能协议服务器和客户端。Netty is an NIO client server framework which enables quick and easy development of network applications such as protocol servers and clients. It greatly simplifies and streamlines network programming such as TCP and UDP socket server.Netty是一个非阻塞IONIO客户端服务器框架能够快速且轻松地开发网络应用程序如协议服务器和客户端。它极大地简化和优化了网络编程如TCP和UDP套接字服务器。为什么需要 Netty方案优点缺点BIOBlocking IO编程简单每个连接一个线程并发能力差NIONon-blocking IO高并发API 复杂需要处理 Selector/Channel/BufferNetty高性能、API 友好、功能丰富需要学习框架本身Reactor 线程模型Netty 采用主从 Reactor 多线程模型架构说明组件数量职责BossGroup主反应器组1 个 EventLoop负责Accept 新连接接收客户端连接后分配给 WorkerGroupWorkerGroup工作反应器组N 个 EventLoop负责处理 IO 读写每个 EventLoop 处理分配给它的连接的读写事件工作流程BossGroup中的 EventLoop 监听端口接收新连接接收到新连接后通过负载均衡策略分配给 WorkerGroup 中的某个 EventLoopWorkerGroup中的 EventLoop 负责处理该连接后续的所有 IO 读写操作核心组件关系ServerBootstrap ├── group(bossGroup, workerGroup) // 线程组 ├── channel(NioServerSocketChannel) // Channel 类型 ├── option(SO_BACKLOG) // 服务端参数 ├── childOption(SO_KEEPALIVE) // 客户端连接参数 └── childHandler(ChannelInitializer) // Pipeline 初始化 └── pipeline.addLast(Handler) // 添加业务处理器Netty 核心组件详解1.ServerBootstrap 与 Bootstrap两者是 Netty 的启动引导类分别用于服务端和客户端的初始化与配置。核心差异ServerBootstrap用于绑定监听端口构建服务端。需要配置两个EventLoopGroup。Bootstrap用于连接到远程服务端构建客户端。通常只需要配置一个EventLoopGroup。线程组配置详解服务端模型 (ServerBootstrap)采用主从Master-SlaveReactor 多线程模型。bossGroup(主线程组)通常一个线程NioEventLoop专门负责接收客户端的 TCP 连接请求。workerGroup(工作线程组)包含多个线程NioEventLoop负责处理已建立连接的 I/O 读写等事件。客户端模型 (Bootstrap)通常只需一个workerGroup来处理所有连接的网络 I/O。使用场景与代码示例服务端示例// 创建主接收连接和从处理I/O线程组EventLoopGroupbossGroupnewNioEventLoopGroup(1);EventLoopGroupworkerGroupnewNioEventLoopGroup();try{ServerBootstrapbnewServerBootstrap();b.group(bossGroup,workerGroup)// 配置双线程组.channel(NioServerSocketChannel.class)// 指定通道类型.childHandler(newChannelInitializerSocketChannel(){// 处理客户端连接的HandlerOverrideprotectedvoidinitChannel(SocketChannelch){// 配置该连接的Pipelinech.pipeline().addLast(newYourServerHandler());}});// 绑定端口开始接收连接ChannelFuturefb.bind(8080).sync();f.channel().closeFuture().sync();}finally{bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}客户端示例EventLoopGroupgroupnewNioEventLoopGroup();try{BootstrapbnewBootstrap();b.group(group)// 单线程组.channel(NioSocketChannel.class)// 客户端通道类型.handler(newChannelInitializerSocketChannel(){OverrideprotectedvoidinitChannel(SocketChannelch){ch.pipeline().addLast(newYourClientHandler());}});// 连接到服务器ChannelFuturefb.connect(127.0.0.1,8080).sync();f.channel().closeFuture().sync();}finally{group.shutdownGracefully();}小结ServerBootstrap.bind()用于服务端监听Bootstrap.connect()用于客户端发起连接。2.EventLoopGroup 与 EventLoop这是 Netty异步事件驱动模型的核心负责所有 I/O 事件、任务的调度与执行。EventLoop单线程执行器本质一个永不退出的无限循环绑定一个独立的 Java 线程。职责在一个线程内串行处理以下两类任务I/O 事件通过 Selector 监听注册在其上的所有 Channel 的网络事件读、写、连接等。异步任务执行用户提交的普通任务Runnable和定时任务ScheduledFutureTask。关键设计一个 EventLoop 在其生命周期内只服务于一个线程但可以注册和管理多个 Channel。保证了每个 Channel 上的所有 I/O 事件和后续的 Handler 处理都在同一个线程中完成天然避免了多线程并发问题。EventLoopGroup线程池管理者本质一组EventLoop的集合是EventLoop的工厂和负载均衡器。作用当一个新的Channel注册时EventLoopGroup会按照一定的策略如轮询从池中选择一个EventLoop与之绑定。之后该Channel的所有生命周期事件都由这个EventLoop处理。线程模型Netty 默认的NioEventLoopGroup创建的EventLoop数量是CPU 核心数 × 2以充分利用多核优势。工作原理简图3.Channel网络连接的抽象Channel是 Netty 对网络套接字如 NIO 的SocketChannel、ServerSocketChannel或其它传输类型如本地传输、嵌入式传输的统一抽象。核心功能代表一个打开的网络连接客户端或一个监听端口服务端。提供所有网络 I/O 操作连接、读、写、绑定、关闭。持有其唯一的ChannelPipeline和ChannelConfig配置。常见实现类NioServerSocketChannel非阻塞 TCP 服务端通道。NioSocketChannel非阻塞 TCP 客户端通道。NioDatagramChannel非阻塞 UDP 通道。EpollSocketChannel基于 Linux epoll 的客户端通道性能更高。Channel 与 EventLoop 的关系一个Channel在生命周期内只注册到一个EventLoop且永不改变确保了线程安全性。4.ChannelPipeline处理器责任链每个Channel都拥有一个唯一的ChannelPipeline。你可以把它想象成一条装配流水线数据或事件是流动的“零件”而ChannelHandler就是流水线上的“加工站”。核心设计双向链表结构内部由一系列ChannelHandlerContext节点构成双向链表每个Context包装了一个Handler。头尾节点HeadContext链表头是出站事件的起点负责将最终的出站数据如ByteBuf转换为底层 I/O 操作如调用SocketChannel.write()。TailContext链表尾是入站事件的终点负责清理未处理的消息和捕获未被处理的异常。事件传播方向入站事件如channelRead、channelActive从Head流向Tail由InboundHandler处理。出站事件如write、connect从Tail流向Head由OutboundHandler处理。事件传播机制Handler 处理完事件后必须决定是否将事件传递给链表中的下一个 Handler。这是通过调用ChannelHandlerContext中的传播方法如ctx.fireChannelRead(msg)实现的。如果某个 Handler 不调用此方法事件传播就会在此中断。示例一个简单的 Pipeline 处理流程5.ChannelHandler业务逻辑处理器ChannelHandler是处理 I/O 事件或拦截 I/O 操作的组件你的核心业务逻辑就在这里实现。分类ChannelInboundHandler处理入站事件和数据。例如连接建立 (channelActive)、数据到达 (channelRead)、异常发生 (exceptionCaught)。ChannelOutboundHandler处理出站事件和操作。例如发起连接 (connect)、数据写入 (write)、关闭连接 (close)。常用适配器避免实现所有方法ChannelInboundHandlerAdapter入站处理器适配器。ChannelOutboundHandlerAdapter出站处理器适配器。SimpleChannelInboundHandlerT一个泛型入站适配器自动释放特定类型消息的资源。实现示例// 一个简单的 Echo 服务器处理器 (入站)Sharable// 标记为可共享需保证线程安全publicclassEchoServerHandlerextendsChannelInboundHandlerAdapter{OverridepublicvoidchannelRead(ChannelHandlerContextctx,Objectmsg){// 收到什么就原样写回去ctx.write(msg);// 暂存到出站缓冲区ctx.flush();// 刷新到网络// 注意此处没有调用 fireChannelRead事件传播终止于此}OverridepublicvoidexceptionCaught(ChannelHandlerContextctx,Throwablecause){cause.printStackTrace();ctx.close();}}6.ChannelInitializerPipeline 初始化器这是一个特殊的ChannelInboundHandler用于在Channel注册到EventLoop后一次性初始化其ChannelPipeline。核心作用提供一个集中化的入口为每个新创建的Channel配置其专属的 Handler 链。在initChannel方法被调用并配置完 Pipeline 后ChannelInitializer会自动将自己从 Pipeline 中移除避免重复初始化。使用场景在ServerBootstrap.childHandler()中为每个新接受的客户端连接配置 Pipeline。在Bootstrap.handler()中为客户端 Channel 配置 Pipeline。代码示例publicclassMyServerInitializerextendsChannelInitializerSocketChannel{OverrideprotectedvoidinitChannel(SocketChannelch){ChannelPipelinepch.pipeline();// 1. 协议处理解决TCP粘包/拆包p.addLast(newLengthFieldBasedFrameDecoder(1024,0,4,0,4));p.addLast(newLengthFieldPrepender(4));// 2. 编解码字节与对象的转换p.addLast(newStringDecoder(StandardCharsets.UTF_8));p.addLast(newStringEncoder(StandardCharsets.UTF_8));// 3. 业务逻辑处理器p.addLast(newEchoServerHandler());// 初始化完成后ChannelInitializer 会自动移除}}// 在引导类中使用ServerBootstrapbnewServerBootstrap();b.childHandler(newMyServerInitializer());// 为每个新连接应用此初始化器线程安全提示ChannelInitializer被标注为Sharable意味着同一个实例可以被多个Channel共享。因此其initChannel方法实现必须是线程安全且无状态的避免使用可能被并发修改的成员变量。总结核心组件协作全景图核心流程引导 (Bootstrap) 配置线程组和通道类型。事件循环 (EventLoop) 线程驱动监听 I/O 事件和执行任务。通道 (Channel) 触发事件交由专属的流水线 (ChannelPipeline) 处理。处理器链 (ChannelHandler) 按顺序处理数据完成解码、业务逻辑、编码等步骤。初始化器 (ChannelInitializer) 在连接建立时为每个 Channel 快速搭建好这条处理器流水线。掌握这七大核心组件及其协作关系是构建高性能、可维护 Netty 网络应用的基础。