Netty 是一个高性能、异步事件驱动的网络应用框架,广泛用于构建 TCP/UDP 客户端和服务器。其核心优势之一就是基于 Reactor 线程模型 实现的高效线程管理机制。
一、Netty 的线程模型概述
Netty 使用的是经典的 Reactor 模式(反应堆模式),它是一种基于事件驱动的设计模式,常用于处理并发 I/O 请求。Netty 的线程模型主要分为两个核心组件:
- Boss Group(Acceptor 线程池)
- Worker Group(I/O 线程池)
这两个线程组分别负责接收连接和处理 I/O 读写操作。
二、线程模型结构图(伪代码逻辑)
Client
│
↓
BossGroup (NioEventLoopGroup)
│ 接收新连接
↓
WorkerGroup (NioEventLoopGroup)
│ 处理 I/O 读写
↓
Handler Pipeline(业务逻辑)
三、线程模型详解
1. Boss Group(主 Reactor)
- 负责监听客户端的连接请求(accept)。
- 通常只包含少量线程(默认是 CPU 核心数)。
- 每个线程绑定一个 Selector,负责监听多个 ServerSocketChannel 上的 accept 事件。
- 一旦有新连接建立,Boss 线程会将该连接注册到 Worker Group 中的一个 EventLoop 上。
2. Worker Group(从 Reactor)
- 负责处理所有已建立连接的 I/O 操作(如 read、write、connect 等)。
- 包含多个线/O 操作由这些线程独立处理。
- 每个 EventLoop 绑定一个 Selector,负责监听多个 Channel 的 I/O 事件。
- 所有的 Handler(如编解码器、自定义处理器)都在对应的 EventLoop 线程中执行,确保线程安全。
四、EventLoop 和 EventLoopGroup 的关系
- EventLoopGroup 是一组 EventLoop 的集合。
- 每个 EventLoop 是一个单线程的事件循环,负责处理一组 Channel 的 I/O 事件。
- Netty 默认使用 NioEventLoopGroup,底层基于 Java NIO 的 Selector。
EventLoopGroup bossGroup = new NioEventLoopGroup(); // 主线程组
EventLoopGroup workerGroup = new NioEventLoopGroup(); // 工作线程组
注意:在客户端或 UDP 场景下,通常只需要一个 EventLoopGroup 即可。
五、线程调度策略
Netty 的线程调度具有以下特点:
- 无锁化设计:每个 Channel 只绑定到一个固定的 EventLoop,所有操作都在同一个线程内完成,避免了多线程竞争。
- 任务队列:可以通过 eventLoop.execute() 向 EventLoop 提交任务,保证任务在线程内部串行执行。
- 公平分配:当新连接到来时,BossGroup 会以轮询方式选择一个 WorkerGroup 的 EventLoop 来注册 Channel。
六、示例代码(服务端)
package org.example;
public class NettyServer {
public static void main(String[] args) throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup(1); // 单个线程用于 accept
EventLoopGroup workerGroup = new NioEventLoopGroup(); // 默认 CPU 核心数
try {
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new StringDecoder());
ch.pipeline().addLast(new StringEncoder());
ch.pipeline().addLast(new SimpleChannelInboundHandler<String>() {
@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) {
System.out.println("收到消息:" + msg);
ctx.writeAndFlush("Echo: " + msg);
}
});
}
});
ChannelFuture future = bootstrap.bind(8080).sync();
future.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
七、性能优化建议
优化点 | 说明 |
线程数设置 | 通常 BossGroup 设置为 1,WorkerGroup 默认为 CPU 核心数 × 2 |
零拷贝支持 | Netty 支持 Direct Buffer,减少内存拷贝 |
背压控制 | 使用 ChannelWritabilityHandler 控制流量 |
自定义线程池 | 对于耗时业务逻辑,可以提交到外部线程池,避免阻塞 EventLoop |
八、适用场景
- 高并发 TCP/UDP 通信(如游戏服务器、即时通讯)
- RPC 框架底层传输层(如 Dubbo、gRPC)
- MQTT、WebSocket 等协议实现
- 实时数据流处理系统