Netty
Netty是一款用于快速开发高性能网络应用程序的Java框架。它封装了网络编程的复杂性,使网络编程和Web技术的最新进展能够被更广泛的开发人员接触到。
Netty的核心特性包括:统一的API支持阻塞和非阻塞传输、简单而强大的线程模型、无连接数据报套接字支持、链式逻辑组件复用。大型公司如Apple、Twitter、Facebook、Google等都在生产环境中使用Netty。
提示
高性能异步网络编程框架
核心组件
Channel
Channel是Java NIO的基本构造,代表到实体的开放连接。它可以打开或关闭,连接或断开连接。
Future与回调
Netty的异步编程模型建立在Future和回调之上。JDK的java.util.concurrent.Future需要手动检查操作是否完成,而Netty的ChannelFuture允许注册监听器,在操作完成时自动回调通知。
ChannelFuture future = channel.connect(address);
future.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) {
if (future.isSuccess()) {
// 连接成功
} else {
Throwable cause = future.cause();
cause.printStackTrace();
}
}
});EventLoop与线程模型
Netty通过EventLoop处理事件。每个Channel都会被分配一个EventLoop,用以处理所有事件。EventLoop由单一线程驱动,在其整个生命周期内不会改变,消除了ChannelHandler中的同步需求。
EventLoop分配策略:
- 服务器端:每个客户端连接对应一个Channel,由EventLoopGroup分配EventLoop处理
- 客户端:连接操作由EventLoopGroup中的一个EventLoop处理
ChannelHandler
ChannelHandler是Netty的核心组件,负责处理入站和出站事件。入站事件包括连接激活、数据读取、异常发生;出站事件包括连接打开关闭、数据写入刷新。
public class EchoServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
ByteBuf in = (ByteBuf) msg;
ctx.write(in); // 写回发送者
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) {
ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)
.addListener(ChannelFutureListener.CLOSE);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}ChannelPipeline
ChannelPipeline持有一条ChannelHandler实例链。入站事件从头部流向尾部,出站事件从尾流向头。这种设计使得业务逻辑与网络处理代码分离,简化了开发过程。
ByteBuf
ByteBuf是Netty的数据容器,相比JDK的ByteBuffer有显著优势:
| 特性 | ByteBuf | JDK ByteBuffer |
|---|---|---|
| 读写索引 | 分离 | 同一索引 |
| 容量扩展 | 支持 | 不支持 |
| 内存管理 | 池化/引用计数 | 无 |
| 组合缓冲区 | CompositeByteBuf | 无 |
ByteBuf使用模式:
- 堆缓冲区:数据存储在JVM堆内存,分配释放快
- 直接缓冲区:使用系统内存,减少JVM堆与系统内存间的复制
- 复合缓冲区:组合多个ByteBuf,如HTTP消息头+体
传输
Netty支持多种传输类型:
| 传输 | 说明 | 适用场景 |
|---|---|---|
| NIO | 非阻塞I/O,使用Selector | 高并发服务器 |
| Epoll | Linux原生EPOLL | Linux生产环境 |
| OIO | 阻塞I/O | 兼容旧代码 |
| Local | JVM内部通信 | 同一JVM进程 |
| Embedded | 用于测试 | 单元测试 |
引导
引导用于配置和启动Netty应用程序。服务器使用ServerBootstrap,客户端使用Bootstrap。
服务器引导示例:
EventLoopGroup group = new NioEventLoopGroup();
ServerBootstrap b = new ServerBootstrap();
b.group(group)
.channel(NioServerSocketChannel.class)
.localAddress(port)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new EchoServerHandler());
}
});
ChannelFuture f = b.bind().sync();
f.channel().closeFuture().sync();
group.shutdownGracefully().sync();客户端引导示例:
EventLoopGroup group = new NioEventLoopGroup();
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)
.remoteAddress(new InetSocketAddress(host, port))
.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new EchoClientHandler());
}
});
ChannelFuture f = b.connect().sync();
f.channel().closeFuture().sync();
group.shutdownGracefully().sync();编解码器
Netty提供丰富的编解码器框架:
解码器
- ByteToMessageDecoder:将字节转为消息对象
- ReplayingDecoder:通过特殊包装使解码更简洁
- MessageToMessageDecoder:消息类型间转换
编码器
- MessageToByteEncoder:消息转为字节
- MessageToMessageEncoder:消息类型间转换
预置编解码器
- SSL/TLS:SecureSocketHandler
- HTTP/HTTPS:HttpServerCodec、HttpClientCodec、HttpObjectAggregator
- WebSocket:WebSocketServerProtocolHandler
- Google Protocol Buffers:ProtobufEncoder、ProtobufDecoder
网络协议
WebSocket
WebSocket实现服务器与客户端的双向通信。Netty提供完整的WebSocket支持,包括帧处理、协议升级等。
UDP
Netty通过DatagramPacket和NioDatagramChannel支持无连接协议。适用于广播、组播等场景。
单元测试
Netty提供EmbeddedChannel用于单元测试,无需启动真实网络连接即可测试ChannelHandler:
EmbeddedChannel channel = new EmbeddedChannel(new EchoServerHandler());
// 测试入站
channel.writeInbound(Unpooled.copiedBuffer("Netty", CharsetUtil.UTF_8));
ByteBuf read = channel.readInbound();
assert read != null;
read.release();
// 测试出站
channel.writeOutbound(Unpooled.copiedBuffer("Test", CharsetUtil.UTF_8));
ByteBuf written = channel.readOutbound();
assert written != null;
written.release();应用场景
Netty被广泛应用于各大互联网公司:
- Twitter Finagle:构建高性能RPC框架,支持负载均衡、故障转移
- Facebook Nifty:基于Netty实现Thrift服务,提升性能
- Firebase:HTTP长连接实现实时数据同步
- Urban Airship:处理大量并发推送通知
- Droplr:移动服务快速上传体验
附录:Maven依赖
<dependencies>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.9.Final</version>
</dependency>
</dependencies>