目录
Reactor 模式是 Netty 高性能的核心设计思想之一,它通过 事件驱动 和 异步非阻塞 I/O 实现高并发处理。
下面通过一个服务端处理多请求的例子,详细解释 Reactor 模式在 Netty 中的实现。
一、Reactor 模式的核心思想
Reactor 模式的核心是 分治:将网络连接的建立(Accept)与 I/O 读写(Read/Write)分离到不同的线程处理,避免单线程阻塞。
核心组件:
- Reactor:监听事件(如连接请求),并将事件分发给对应的处理器。
- Acceptor:处理新连接建立事件。
- Handler:处理已建立连接的 I/O 读写事件。
在 Netty 中,Reactor 模式的实现体现为 主从多线程模型:
- 主 Reactor:负责处理连接建立(
bossGroup
)。 - 子 Reactor:负责处理 I/O 读写(
workerGroup
)。
二、Netty 中的 Reactor 模式实现
1. 服务端代码示例
以下是一个 Netty 服务端代码,演示如何接受多个客户端请求:
public class ReactorServerExample {
public static void main(String[] args) {
// 主 Reactor(处理连接请求)
EventLoopGroup bossGroup = new NioEventLoopGroup(1); // 1 个线程
// 子 Reactor(处理 I/O 读写)
EventLoopGroup workerGroup = new NioEventLoopGroup(); // 默认 CPU 核心数 * 2
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new ServerHandler());
}
});
// 绑定端口并启动
ChannelFuture future = serverBootstrap.bind(8080).sync();
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
2. 处理请求的 Handler
public class ServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
// 处理客户端请求
ByteBuf buf = (ByteBuf) msg;
System.out.println("Received: " + buf.toString(CharsetUtil.UTF_8));
ctx.writeAndFlush(Unpooled.copiedBuffer("Hello Client!", CharsetUtil.UTF_8));
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}
三、运行流程解析(结合 Reactor 模式)
假设客户端 A 和 B 同时连接服务器:
- 主 Reactor(bossGroup)
-
- 主 Reactor 的
NioEventLoop
线程负责监听端口(如 8080)。 - 当客户端 A 和 B 发起连接请求时,主 Reactor 的线程会 顺序处理这些连接请求。
- 每接受一个新连接(
accept
事件),主 Reactor 会将新连接的Channel
注册到子 Reactor(workerGroup
)中的一个EventLoop
。
- 主 Reactor 的
- 子 Reactor(workerGroup)
-
- 子 Reactor 包含多个
EventLoop
,每个EventLoop
绑定一个线程。 - 客户端 A 和 B 的
Channel
被分配到不同的EventLoop
(例如轮询分配)。 - 当客户端发送数据时,子 Reactor 的线程负责处理读事件(
channelRead
),执行ServerHandler
中的业务逻辑,并返回响应。
- 子 Reactor 包含多个
四、关键点说明
- 非阻塞 I/O
-
- 主 Reactor 和子 Reactor 均使用 NIO 的非阻塞模式,单线程可处理多个连接。
- 例如:一个
EventLoop
线程可以处理多个Channel
的 I/O 事件。
- 线程隔离
-
- 主 Reactor 的线程仅处理连接建立,避免 I/O 操作阻塞新连接的接收。
- 子 Reactor 的线程专注于 I/O 读写,充分利用多核 CPU。
- 事件驱动
-
- 所有操作(连接、读、写)均由事件触发,避免轮询浪费资源。
- 例如:当数据到达时,Netty 自动触发
channelRead
事件。
五、与传统模型的对比
模型 |
线程开销 |
并发能力 |
资源利用率 |
传统 BIO |
每个连接一个线程 |
低(线程数受限) |
低(线程阻塞) |
Reactor 模式 |
固定线程池 |
高(单线程处理多连接) |
高(非阻塞) |
六、总结
通过 Reactor 模式,Netty 实现了:
- 高并发:单线程处理多连接,减少线程切换开销。
- 低延迟:非阻塞 I/O 确保事件快速响应。
- 易扩展:责任链模式(Pipeline)允许灵活添加业务逻辑。
在示例中,主 Reactor 处理连接,子 Reactor 处理 I/O,多个客户端请求被高效分发到不同线程,最终由 ServerHandler
处理业务逻辑。这就是 Netty 高性能的核心秘密!