Netty线程模型

Netty解决的问题

  • NIO 的类库和 API 繁杂, 使用麻烦: 需要熟练掌握Selector、 ServerSocketChannel、
    SocketChannel、 ByteBuffer等。
  • 开发工作量和难度都非常大: 例如客户端面临断连重连、 网络闪断、心跳处理、半包读写、 网络拥塞 和异常流的处理等等。
  • Netty 对 JDK 自带的 NIO 的 API 进行了良好的封装,解决了上述问题。且Netty拥有高性能、 吞吐 量更高,延迟更低,减少资源消耗,最小化不必要的内存复制等优点。
  • Netty 现在都在用的是4.x,5.x版本已经废弃,Netty 4.x 需要JDK 6以上版本支持

Netty的使用场景

  1. 互联网行业:在分布式系统中,各个节点之间需要远程服务调用,高性能的 RPC 框架必不可少, Netty 作为异步高性能的通信框架,往往作为基础通信组件被这些 RPC 框架使用。典型的应用有:阿 里分布式服务框架 Dubbo 的 RPC 框架使用 Dubbo 协议进行节点间通信,Dubbo 协议默认使用 Netty 作为基础通信组件,用于实现。各进程节点之间的内部通信。Rocketmq底层也是用的Netty作 为基础通信组件。
  2. 游戏行业:无论是手游服务端还是大型的网络游戏,Java 语言得到了越来越广泛的应用。Netty 作为高性能的基础通信组件,它本身提供了 TCP/UDP 和 HTTP 协议栈。
  3. 大数据领域:经典的 Hadoop 的高性能通信和序列化组件 Avro 的 RPC 框架,默认采用 Netty 进行跨界点通信,它的 Netty Service 基于 Netty 框架二次封装实现。 netty相关开源项目:https://netty.io/wiki/related-projects.html

Netty线程模型

在这里插入图片描述
模型解释

  1. Netty 抽象出两组线程池BossGroup和WorkerGroup,BossGroup专门负责接收客户端的连接, WorkerGroup专门负责网络的读写
  2. BossGroup和WorkerGroup类型都是NioEventLoopGroup
  3. NioEventLoopGroup 相当于一个事件循环线程组, 这个组中含有多个事件循环线程 , 每一个事件 循环线程是NioEventLoop
  4. 每个NioEventLoop都有一个selector , 用于监听注册在其上的socketChannel的网络通讯
  5. 每个Boss NioEventLoop线程内部循环执行的步骤有3 步:
    • 处理accept事件 , 与client 建立连接 , 生成 NioSocketChannel
    • 将NioSocketChannel注册到某个worker NIOEventLoop上的selector
    • 处理任务队列的任务 , 即runAllTasks
  6. 每个worker NIOEventLoop线程循环执行的步骤
    • 轮询注册到自己selector上的所有NioSocketChannel 的read, write事件
    • 处理 I/O 事件, 即read , write 事件, 在对应NioSocketChannel 处理业务
    • runAllTasks处理任务队列TaskQueue的任务 ,一些耗时的业务处理一般可以放入
      TaskQueue中慢慢处理,这样不影响数据在 pipeline 中的流动处理
  7. 每个worker NIOEventLoop处理NioSocketChannel业务时,会使用 pipeline (管道),管道中维护 了很多 handler 处理器用来处理 channel 中的数据

ByteBuf详解

从结构上来说,ByteBuf 由一串字节数组构成。数组中每个字节用来存放信息。
ByteBuf 提供了两个索引,一个用于读取数据,一个用于写入数据。这两个索引通过在字节数 组中移动,来定位需要读或者写信息的位置。
当从 ByteBuf 读取时,它的 readerIndex(读索引)将会根据读取的字节数递增。 同样,当写 ByteBuf 时,它的 writerIndex 也会根据写入的字节数进行递增。
在这里插入图片描述
需要注意的是极限的情况是 readerIndex 刚好读到了 writerIndex 写入的地方。
如果 readerIndex 超过了 writerIndex 的时候,Netty 会抛出 IndexOutOf-BoundsException 异常。

### Netty 线程模型概述 Netty 是一种基于 NIO 的高性能网络框架,它的线程模型设计非常精巧,能够高效处理大量并发连接。Netty 使用了 Reactor 模式来实现事件驱动机制,其中核心组件之一就是 `EventLoop` 和其对应的线程池。 #### 1. **Reactor 模型** Netty 基于经典的 Reactor 设计模式运行[^1]。在这种模式下,I/O 操作由专门的线程负责监听并分发到业务逻辑处理器中执行。具体来说,Netty 将 I/O 多路复用器(Selector)封装到了 EventLoop 中,使得开发者可以专注于编写业务逻辑而无需关心底层复杂的 I/O 实现细节。 #### 2. **EventLoop 组件** 在 Netty 中,`EventLoop` 负责管理一组 Channel 并轮询这些 Channel 上发生的事件。每一个 `Channel` 都绑定到唯一的 `EventLoop` 实例上,在整个生命周期内不会改变这种绑定关系[^2]。这意味着对于同一个客户端请求而言,所有的读写操作都会被分配给相同的线程去完成,从而避免了跨线程共享状态所带来的同步开销。 #### 3. **线程分工** 通常情况下,Netty 的线程分为两类:Boss Group 和 Worker Group。 - **Boss Group**: 主要职责在于接受新的连接请求并将新建立好的 Socket 分配至下一个阶段——Worker Group 进行进一步处理; - **Worker Group**: 则承担起实际的数据收发任务以及调用用户定义的各种回调方法来响应不同的网络行为(比如接收到消息后的解码编码过程)[^3]。 当一个新的 TCP 客户端尝试接入服务器时,流程如下所示: ```plaintext Client -> BossGroup (accepts connection) -> WorkerGroup (handles IO operations) ``` 每组都维护着自己的 NioEventLoop 或 EpollEventLoop 对象集合,并通过它们内部所包含的选择键集不断查询是否有就绪的任务待处理;一旦发现某个信道上有可利用资源,则立即触发相应的方法链路直至最终达成目标功能为止。 #### 4. **性能优化策略** 为了提高系统的吞吐量和降低延迟时间,可以通过调整以下几个方面来进行针对性改进: - **增加线程数**:适当增大 boss/worker groups size 参数可以让更多 CPU 参与进来共同协作完成繁重的工作负载; - **亲缘调度**:如果硬件支持 NUMA 架构的话,考虑让特定范围内的 channel 总是由固定几个临近物理位置上的 core 来服务可能会带来额外好处因为减少了内存访问跨越节点带来的成本; - **零拷贝技术应用**:充分利用操作系统层面提供的 sendfile() 函数或者 mmap 映射文件等方式减少不必要的数据搬移动作次数进而提升效率. 以下是创建自定义配置的一个简单例子展示如何设置多线程环境下的 netty server 启动参数: ```java import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; public class NettyServer { public static void main(String[] args) throws Exception { int port = 8080; // 创建两个线程组分别用于接收新连接(boss group)和服务已存在的连接(worker group). EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class); // 设置其他选项... ChannelFuture f = b.bind(port).sync(); System.out.println("Server started and listen on " + f.channel().localAddress()); f.channel().closeFuture().sync(); } finally { workerGroup.shutdownGracefully(); bossGroup.shutdownGracefully(); } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值