🏗️ 整体架构概览
这是一个基于 Netty 的 RPC 框架,采用了经典的客户端-服务端架构,主要包含以下几个核心模块:
📁 目录结构
rpc-framework-simple/src/main/java/github/javaguide/remoting/transport/netty/
├── codec/ # 编解码器
│ ├── RpcMessageEncoder.java
│ └── RpcMessageDecoder.java
├── client/ # 客户端组件
│ ├── NettyRpcClient.java
│ ├── NettyRpcClientHandler.java
│ ├── ChannelProvider.java
│ └── UnprocessedRequests.java
└── server/ # 服务端组件
├── NettyRpcServer.java
└── NettyRpcServerHandler.java
🔧 核心组件分析
1. 协议设计
框架定义了自定义的 RPC 协议格式:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
+-----+-----+-----+-----+--------+----+----+----+------+-----------+-------+----- --+-----+-----+-------+
| magic code |version | full length | messageType| codec|compress| RequestId |
+-----------------------+--------+---------------------+-----------+-----------+-----------+------------+
| body |
+-------------------------------------------------------------------------------------------------------+
- 4B magic code(魔法数)
- 1B version(版本)
- 4B full length(消息长度)
- 1B messageType(消息类型)
- 1B compress(压缩类型)
- 1B codec(序列化类型)
- 4B requestId(请求ID)
- body(消息体)
2. 数据传输对象
RpcMessage - 传输消息包装
public class RpcMessage {
private byte messageType; // 消息类型
private byte codec; // 序列化类型
private byte compress; // 压缩类型
private int requestId; // 请求ID
private Object data; // 消息数据
}
RpcRequest - RPC 请求
public class RpcRequest {
private String requestId; // 请求ID
private String interfaceName; // 接口名
private String methodName; // 方法名
private Object[] parameters; // 参数
private Class<?>[] paramTypes; // 参数类型
private String version; // 版本
private String group; // 分组
}
RpcResponse - RPC 响应
public class RpcResponse<T> {
private String requestId; // 请求ID
private Integer code; // 响应码
private String message; // 响应消息
private T data; // 响应数据
}
🚀 服务端架构
NettyRpcServer - 服务端启动器
public class NettyRpcServer {
public static final int PORT = 9998;
public void start() {
// 1. 创建线程组
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
DefaultEventExecutorGroup serviceHandlerGroup = new DefaultEventExecutorGroup(
RuntimeUtil.cpus() * 2,
ThreadPoolFactoryUtil.createThreadFactory("service-handler-group", false)
);
// 2. 配置服务端启动器
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childOption(ChannelOption.TCP_NODELAY, true)
.childOption(ChannelOption.SO_KEEPALIVE, true)
.option(ChannelOption.SO_BACKLOG, 128)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ChannelPipeline p = ch.pipeline();
// 3. 配置处理器链
p.addLast(new IdleStateHandler(30, 0, 0, TimeUnit.SECONDS));
p.addLast(new RpcMessageEncoder());
p.addLast(new RpcMessageDecoder());
p.addLast(serviceHandlerGroup, new NettyRpcServerHandler());
}
});
}
}
NettyRpcServerHandler - 服务端消息处理器
public class NettyRpcServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
if (msg instanceof RpcMessage) {
RpcMessage rpcMessage = (RpcMessage) msg;
byte messageType = rpcMessage.getMessageType();
if (messageType == RpcConstants.HEARTBEAT_REQUEST_TYPE) {
// 处理心跳请求
rpcMessage.setMessageType(RpcConstants.HEARTBEAT_RESPONSE_TYPE);
rpcMessage.setData(RpcConstants.PONG);
} else {
// 处理RPC请求
RpcRequest rpcRequest = (RpcRequest) rpcMessage.getData();
Object result = rpcRequestHandler.handle(rpcRequest);
RpcResponse<Object> rpcResponse = RpcResponse.success(result, rpcRequest.getRequestId());
rpcMessage.setData(rpcResponse);
}
ctx.writeAndFlush(rpcMessage);
}
}
}
📱 客户端架构
NettyRpcClient - 客户端连接器
public class NettyRpcClient implements RpcRequestTransport {
public NettyRpcClient() {
// 1. 初始化客户端启动器
eventLoopGroup = new NioEventLoopGroup();
bootstrap = new Bootstrap();
bootstrap.group(eventLoopGroup)
.channel(NioSocketChannel.class)
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ChannelPipeline p = ch.pipeline();
// 2. 配置处理器链
p.addLast(new IdleStateHandler(0, 5, 0, TimeUnit.SECONDS));
p.addLast(new RpcMessageEncoder());
p.addLast(new RpcMessageDecoder());
p.addLast(new NettyRpcClientHandler());
}
});
}
@Override
public Object sendRpcRequest(RpcRequest rpcRequest) {
CompletableFuture<RpcResponse<Object>> resultFuture = new CompletableFuture<>();
// 1. 获取服务地址
InetSocketAddress inetSocketAddress = serviceDiscovery.lookupService(rpcRequest);
// 2. 获取或创建连接
Channel channel = getChannel(inetSocketAddress);
if (channel.isActive()) {
// 3. 发送请求
unprocessedRequests.put(rpcRequest.getRequestId(), resultFuture);
RpcMessage rpcMessage = RpcMessage.builder()
.data(rpcRequest)
.codec(SerializationTypeEnum.HESSIAN.getCode())
.compress(CompressTypeEnum.GZIP.getCode())
.messageType(RpcConstants.REQUEST_TYPE)
.build();
channel.writeAndFlush(rpcMessage);
}
// 4. 等待响应
return resultFuture.get();
}
}
NettyRpcClientHandler - 客户端消息处理器
public class NettyRpcClientHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
if (msg instanceof RpcMessage) {
RpcMessage tmp = (RpcMessage) msg;
byte messageType = tmp.getMessageType();
if (messageType == RpcConstants.HEARTBEAT_RESPONSE_TYPE) {
// 处理心跳响应
log.info("heart [{}]", tmp.getData());
} else if (messageType == RpcConstants.RESPONSE_TYPE) {
// 处理RPC响应
RpcResponse<Object> rpcResponse = (RpcResponse<Object>) tmp.getData();
unprocessedRequests.complete(rpcResponse);
}
}
}
}
🔄 完整调用链路
调用链路
客户端发起请求流程:
-
请求发起 RpcClientProxy.invoke() → NettyRpcClient.sendRpcRequest()
-
服务发现 ServiceDiscovery.lookupService() → 获取服务地址
-
连接管理 ChannelProvider.get() → 获取或创建连接 NettyRpcClient.doConnect() → 建立新连接(如需要)
-
请求发送 构建 RpcMessage → UnprocessedRequests.put() → 注册待处理请求 → Channel.writeAndFlush() → 发送到网络
-
编码过程 RpcMessage → RpcMessageEncoder.encode() → ByteBuf
服务端处理流程:
-
消息接收 Netty EventLoop → ChannelPipeline
-
解码过程 ByteBuf → RpcMessageDecoder.decode() → RpcMessage
-
业务处理 NettyRpcServerHandler.channelRead() → RpcRequestHandler.handle() → ServiceProvider.getService() → 获取服务实例 → Method.invoke() → 反射调用目标方法
-
响应发送 构建 RpcResponse → 包装为 RpcMessage → RpcMessageEncoder.encode() → Channel.writeAndFlush()
客户端接收响应:
-
响应接收 Netty EventLoop → ChannelPipeline
-
解码响应 ByteBuf → RpcMessageDecoder.decode() → RpcMessage
-
完成请求 NettyRpcClientHandler.channelRead() → UnprocessedRequests.complete() → CompletableFuture.complete() → 返回结果给调用方
🛠️ 关键特性
1. 连接管理
ChannelProvider:管理客户端到服务端的连接池- 连接复用:相同地址复用已建立的连接
- 连接检测:自动检测连接状态,失效时重新建立
2. 异步处理
UnprocessedRequests:管理未完成的请求CompletableFuture:实现异步请求-响应匹配- 通过
requestId关联请求和响应
3. 心跳机制
- 客户端:5秒无写操作时发送心跳
- 服务端:30秒无读操作时关闭连接
- 保证连接活性,及时清理死连接
4. 线程模型
- Boss线程组:处理连接接受
- Worker线程组:处理I/O操作
- 业务线程组:处理具体的RPC调用(避免阻塞I/O线程)
5. 编解码
- 自定义协议格式
- 支持多种序列化方式(Hessian、Protostuff等)
- 支持压缩(GZIP)
- 基于
LengthFieldBasedFrameDecoder解决粘包拆包
Demo
代码 demo:github.com/liuyjray/gu…
1. Netty 核心组件架构
Netty 的核心架构基于以下几个关键组件:
1.1 EventLoopGroup(事件循环组)
// 服务端:两个线程组
EventLoopGroup bossGroup = new NioEventLoopGroup(1); // 处理连接
EventLoopGroup workerGroup = new NioEventLoopGroup(); // 处理I/O
// 客户端:一个线程组
EventLoopGroup group = new NioEventLoopGroup();
职责分工:
- bossGroup:专门负责接收客户端连接请求
- workerGroup:负责处理已建立连接的 I/O 操作
1.2 Bootstrap(启动器)
- ServerBootstrap:服务端启动器,用于配置和启动服务端
- Bootstrap:客户端启动器,用于配置和启动客户端
1.3 Channel(通道)
- NioServerSocketChannel:服务端通道,基于 NIO 的非阻塞服务端套接字
- NioSocketChannel:客户端通道,基于 NIO 的非阻塞客户端套接字
1.4 ChannelHandler(处理器)
- ChannelInboundHandler:入站处理器,处理读取数据
- ChannelOutboundHandler:出站处理器,处理写入数据
2. 简单示例的代码结构
2.1 服务端结构
public void start() throws InterruptedException {
// 1. 创建线程组
// bossGroup 用于接收客户端连接
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
// workerGroup 用于处理客户端请求
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
// 2. 创建服务端启动器
ServerBootstrap serverBootstrap = new ServerBootstrap();
// 3. 配置启动器
serverBootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class) // 设置服务端 Channel 类型
.option(ChannelOption.SO_BACKLOG, 128) // 设置连接队列大小
.childOption(ChannelOption.SO_KEEPALIVE, true) // 保持连接活跃
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
// 4. 设置处理器链
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new StringDecoder());
pipeline.addLast(new StringEncoder());
pipeline.addLast(new EchoServerHandler());
}
});
// 5. 绑定端口并启动服务
ChannelFuture future = serverBootstrap.bind(port).sync();
System.out.println("🚀 Netty 服务端启动成功,监听端口:" + port);
// 6. 等待服务端关闭
future.channel().closeFuture().sync();
} finally {
// 7. 优雅关闭线程组
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
2.2 客户端结构
public void start() throws InterruptedException {
// 1. 创建线程组
EventLoopGroup group = new NioEventLoopGroup();
try {
// 2. 创建客户端启动器
Bootstrap bootstrap = new Bootstrap();
// 3. 配置启动器
bootstrap.group(group)
.channel(NioSocketChannel.class) // 设置客户端 Channel 类型
.option(ChannelOption.SO_KEEPALIVE, true) // 保持连接活跃
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
// 4. 设置处理器链
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new StringDecoder());
pipeline.addLast(new StringEncoder());
pipeline.addLast(new EchoClientHandler());
}
});
// 5. 连接服务端
ChannelFuture future = bootstrap.connect(host, port).sync();
Channel channel = future.channel();
// 6. 发送消息
while (true) {
String input = scanner.nextLine();
if ("quit".equalsIgnoreCase(input)) {
break;
}
channel.writeAndFlush(input);
}
} finally {
// 7. 优雅关闭
group.shutdownGracefully();
}
}
2.3 消息处理器
服务端处理器:
public class EchoServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
String message = (String) msg;
System.out.println("📨 服务端接收到消息:" + message);
// 回显消息给客户端
String response = "服务端回复:" + message;
ctx.writeAndFlush(response);
}
@Override
public void channelActive(ChannelHandlerContext ctx) {
System.out.println("🔗 客户端连接建立:" + ctx.channel().remoteAddress());
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
System.err.println("💥 服务端发生异常:" + cause.getMessage());
ctx.close();
}
}
3. ChannelPipeline 处理器链
ChannelPipeline 是 Netty 的核心概念,它是一个处理器链:
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ChannelPipeline pipeline = ch.pipeline();
// 添加处理器(按顺序)
pipeline.addLast(new StringDecoder()); // 解码器
pipeline.addLast(new StringEncoder()); // 编码器
pipeline.addLast(new EchoServerHandler()); // 业务处理器
}
});
3.1 处理器执行顺序
-
入站(Inbound) :从前往后执行
网络数据 → StringDecoder → StringEncoder → EchoServerHandler → 业务处理 -
出站(Outbound) :从后往前执行
业务数据 → EchoServerHandler → StringEncoder → StringDecoder → 网络发送
3.2 处理器类型
| 处理器类型 | 作用 | 典型实现 |
|---|---|---|
| 编解码器 | 数据格式转换 | StringDecoder, StringEncoder |
| 协议处理器 | 协议解析 | HttpServerCodec, WebSocketFrameDecoder |
| 业务处理器 | 业务逻辑 | 自定义 Handler |
| 工具处理器 | 辅助功能 | LoggingHandler, IdleStateHandler |