开始
官网:Netty: Home
Netty 是高性能、异步事件驱动的网络应用框架,常用于 RPC、网关、长连接、IM、游戏服务器等场景。它封装了 Java NIO 的复杂细节,让开发者更容易编写高性能网络程序。
为什么需要 Netty
直接使用 Java NIO 需要处理 Selector、Channel、Buffer、事件循环、半包粘包、线程模型等细节,代码复杂且容易出错。Netty 把这些能力抽象成更清晰的组件。
核心流程
mermaid
flowchart TD
A["客户端连接"] --> B["BossGroup 接收连接"]
B --> C["注册到 WorkerGroup"]
C --> D["ChannelPipeline"]
D --> E["Decoder 解码"]
E --> F["业务 Handler"]
F --> G["Encoder 编码"]
G --> H["响应客户端"]这个流程背后的原理是:服务端端口由 BossGroup 监听,新连接建立后变成一个 SocketChannel,再注册到 WorkerGroup 的某个 EventLoop。之后这个连接上的读、写、关闭事件通常都由同一个 EventLoop 处理,再通过 Pipeline 进入不同 Handler。
为什么这样设计:接收连接和处理数据是两类不同工作。接收连接要快,不能被业务逻辑拖慢;处理数据要稳定,要能把协议解析、业务处理、响应编码拆清楚。如果把所有事情都写在一个线程或一个方法里,连接数上来后就会很难定位到底是接入慢、解码慢、业务慢还是写回慢。
核心组件
| 组件 | 说明 |
|---|---|
| EventLoopGroup | 线程组,处理连接和 IO 事件 |
| Channel | 网络连接抽象 |
| ChannelPipeline | Handler 责任链 |
| ChannelHandler | 编解码、业务处理、异常处理 |
| ByteBuf | Netty 自定义字节缓冲区 |
| Bootstrap | 客户端或服务端启动辅助类 |
学习目录
学习建议
先理解 Reactor 线程模型,再看 ChannelPipeline。Netty 的核心是“事件进入 Pipeline 后,被一组 Handler 按顺序处理”。
常见风险
| 风险 | 后果 | 规避方式 |
|---|---|---|
| EventLoop 中写耗时代码 | 同一个 EventLoop 上的多个连接一起变慢 | 慢 SQL、远程调用、大计算放到业务线程池 |
| 没有定义协议边界 | TCP 粘包半包导致消息解析错乱 | 使用 LengthFieldBasedFrameDecoder 等拆包器 |
| Handler 顺序随意放 | 解码器、鉴权器、编码器不按预期执行 | 按入站和出站方向设计 Pipeline |
| 忽略连接关闭 | 在线用户表残留无效连接 | 在 channelInactive 中清理资源 |
| 忽略 ByteBuf 释放 | 堆外内存泄漏 | 使用 SimpleChannelInboundHandler 或手动 release |
代码 Demo:最小 Netty 服务端
java
public class NettyServer {
public static void main(String[] args) throws InterruptedException {
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
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) {
ctx.writeAndFlush("server receive: " + msg);
}
});
}
});
ChannelFuture future = bootstrap.bind(8080).sync();
future.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}这个 Demo 展示了 Netty 服务端的基本结构:BossGroup 接收连接,WorkerGroup 处理 IO,Pipeline 中按顺序放入解码器、编码器和业务 Handler。
