场景一:游戏服务器 —— 万人同屏的底层引擎
核心痛点
- 高并发连接:万人同时在线,TCP 长连接管理。
- 低延迟通信:实时战斗、技能同步需毫秒级响应。
- 协议复杂性:自定义二进制协议,高效序列化与反序列化。
Netty 实战方案
1. 自定义协议栈(避免粘包/拆包)
public class GameProtocolDecoder extends ByteToMessageDecoder {
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
if (in.readableBytes() < 4) return; // 头部长度不足,等待
in.markReaderIndex();
int length = in.readInt();
if (in.readableBytes() < length) {
in.resetReaderIndex(); // 数据不完整,重置读取位置
return;
}
byte[] data = new byte[length];
in.readBytes(data);
out.add(GamePacket.parseFrom(data)); // Protobuf 反序列化
}
}
2. 连接管理与心跳检测
// 用户连接管理
public class GameSessionManager {
private static final ConcurrentHashMap<Long, Channel> sessions = new ConcurrentHashMap<>();
public static void addSession(Long userId, Channel channel) {
sessions.put(userId, channel);
channel.closeFuture().addListener(future -> sessions.remove(userId));
}
}
// 心跳处理
ch.pipeline().addLast(new IdleStateHandler(30, 0, 0));
ch.pipeline().addLast(new HeartbeatHandler());
3. 异步事件驱动架构
- EventLoopGroup 配置:BossGroup 处理连接,WorkerGroup 处理 I/O。
- 零拷贝优化:使用
CompositeByteBuf合并多个 Buffer,减少内存复制。
场景二:即时通讯(IM) —— 亿级消息并发的幕后推手
核心需求
- 消息实时推送:单聊、群聊消息秒级达。
- 海量连接维持:WebSocket 长连接管理。
- 消息可靠性:离线消息存储、QoS 质量保证。
Netty 核心技术
1. WebSocket 全双工通信
public class WebSocketServerInitializer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel ch) {
ch.pipeline()
.addLast(new HttpServerCodec())
.addLast(new HttpObjectAggregator(65536))
.addLast(new WebSocketServerProtocolHandler("/ws"))
.addLast(new IMHandler()); // 自定义消息处理器
}
}
2. 分布式会话管理
- Redis 存储:用户ID与Channel ID映射,跨节点消息路由。
- 消息重试机制:基于唯一消息ID实现至少一次投递。
3. 消息压缩与加密
// Protobuf + GZIP 压缩
public class MessageEncoder extends MessageToByteEncoder<IMessage> {
@Override
protected void encode(ChannelHandlerContext ctx, IMessage msg, ByteBuf out) {
byte[] data = msg.toByteArray();
byte[] compressed = compressWithGZIP(data); // 自定义压缩
out.writeInt(compressed.length);
out.writeBytes(compressed);
}
}
场景三:RPC 框架 —— 微服务通信的血管网络
核心设计
- 透明化调用:像调用本地方法一样调用远程服务。
- 高性能序列化:Protobuf/Kryo 替代 JSON,提升编解码效率。
- 连接池化:避免频繁创建连接的开销。
Netty 关键实现
1. 动态代理与协议封装
// 客户端代理
public class RpcProxy implements InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args) {
RpcRequest request = buildRequest(method, args);
Channel channel = ConnectionPool.getChannel();
channel.writeAndFlush(request).sync(); // 同步等待响应
return parseResponse(channel);
}
}
2. 响应式编解码管道
// 协议头定义:魔数(4) + 长度(4) + 序列化类型(1)
public class RpcDecoder extends ByteToMessageDecoder {
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
if (in.readableBytes() < 9) return;
in.markReaderIndex();
int magic = in.readInt();
int length = in.readInt();
byte serializationType = in.readByte();
// ... 根据类型反序列化
}
}
3. 熔断与降级
- Hystrix 集成:在 Netty 客户端实现熔断机制。
- 超时控制:通过
ReadTimeoutHandler检测未响应请求。
场景四:HTTP 服务器 —— 高性能API网关的基石
核心优化
- 异步非阻塞:对比 Tomcat 的线程池模型,Netty 更擅长应对突发流量。
- 灵活路由:自定义路由规则,支持灰度发布、限流。
- 静态资源处理:零拷贝发送文件,提升吞吐量。
Netty 代码示例
1. 异步请求处理
public class HttpHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) {
CompletableFuture.supplyAsync(() -> processRequest(request))
.thenAccept(response -> writeResponse(ctx, response));
}
}
2. 文件传输优化
// 零拷贝发送文件
FileRegion fileRegion = new DefaultFileRegion(file, 0, file.length());
ctx.write(fileRegion);
3. 链路监控
- Micrometer 集成:实时统计 QPS、延迟等指标。
- OpenTracing:基于 Brave 实现分布式追踪。
场景五:物联网(IoT) —— 百万设备并发的终极试炼
关键挑战
- 设备协议多样性:MQTT、CoAP、自定义二进制协议。
- 海量心跳管理:设备保活与僵尸连接清理。
- 边缘计算:本地数据处理与云端同步。
Netty 解决方案
1. MQTT 协议支持
// 使用 Netty-MQTT 编解码库
ch.pipeline().addLast(MqttEncoder.INSTANCE);
ch.pipeline().addLast(new MqttDecoder());
ch.pipeline().addLast(new MqttHandler());
2. 连接保活与断线重连
// 服务端心跳检测
ch.pipeline().addLast(new IdleStateHandler(0, 0, 60));
ch.pipeline().addLast(new DeviceHeartbeatHandler());
// 客户端自动重连
Bootstrap bootstrap = new Bootstrap();
bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000)
.handler(new ReconnectHandler());
3. 消息批量压缩上传
// 累积10条数据后批量发送
public class BatchUploadHandler extends ChannelDuplexHandler {
private List<SensorData> buffer = new ArrayList<>();
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
buffer.add((SensorData) msg);
if (buffer.size() >= 10) {
ctx.writeAndFlush(new BatchData(buffer));
buffer.clear();
}
}
}