目录

RPC Framework

一个轻量级的 Java RPC(远程过程调用)框架,支持服务注册与发现、动态代理、多种序列化方式。

特性

  • 透明调用: 通过动态代理实现远程方法调用透明化
  • 服务注册与发现: 支持本地注册中心和 Nacos 注册中心
  • 多种序列化: 支持 JSON、Kryo、Hessian、Protobuf 四种序列化方式
  • 连接池: 支持长连接复用,提升性能
  • 重试机制: 内置重试策略,支持指数退避
  • 超时控制: 支持方法级超时配置
  • 灵活的通信层: 基于 Socket 的 BIO 通信,支持线程池处理请求
  • IDL编译: 自定义IDL语言,支持生成Java/Python/Go代码
  • 跨语言调用: 通过IDL定义服务接口,生成多语言客户端实现
  • 简单易用: 简洁的 API 设计,快速上手

项目结构

rpc/
├── src/main/java/com/rpc/           # 框架核心源码
│   ├── codec/              # 编解码模块
│   ├── config/            # 配置模块
│   ├── exception/         # 异常定义
│   ├── idl/               # IDL编译器模块
│   │   ├── compiler/      # 编译器主类
│   │   ├── exception/     # 编译异常
│   │   ├── generator/     # 代码生成器
│   │   ├── lexer/         # 词法分析器
│   │   ├── parser/        # 语法分析器
│   │   └── semantic/     # 语义分析器
│   ├── loadbalancer/      # 负载均衡模块
│   ├── protocol/          # 协议定义
│   ├── proxy/             # 动态代理模块
│   ├── registry/          # 注册中心模块
│   ├── retry/             # 重试策略模块
│   ├── serialization/     # 序列化模块
│   └── transport/         # 通信模块
├── demo/demo0/             # 示例与测试目录
│   ├── idl/               # IDL定义文件
│   ├── generated/         # 生成的跨语言代码
│   ├── java/              # Java示例代码
│   └── test/              # 单元测试
├── docs/                   # 文档目录
├── pom.xml                 # Maven 配置
└── README.md

快速开始

1. 添加依赖

<dependency>
    <groupId>com.rpc</groupId>
    <artifactId>rpc-framework</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

2. 定义服务接口

public interface HelloService {
    String sayHello(String name);
    int add(int a, int b);
}

3. 实现服务

public class HelloServiceImpl implements HelloService {
    @Override
    public String sayHello(String name) {
        return "Hello, " + name + "!";
    }
    
    @Override
    public int add(int a, int b) {
        return a + b;
    }
}

4. 服务端启动

// 创建注册中心
ServiceRegistry registry = new LocalServiceRegistry();

// 创建服务端并注册服务
SocketServer server = new SocketServer(registry);
server.register(new HelloServiceImpl(), HelloService.class.getName());

// 启动服务
server.start(8888);

5. 客户端调用

// 创建注册中心(与服务端共享)
ServiceRegistry registry = new LocalServiceRegistry();

// 创建客户端
RegistryAwareClient client = new RegistryAwareClient(registry);

// 创建代理对象
HelloService helloService = RpcClientProxy.createProxy(HelloService.class, client);

// 透明调用远程方法
String result = helloService.sayHello("World");  // 返回 "Hello, World!"
int sum = helloService.add(10, 20);              // 返回 30

模块说明

协议模块 (protocol)

定义 RPC 请求和响应消息格式:

  • RpcRequest: 封装调用请求(接口名、方法名、参数类型、参数值)
  • RpcResponse: 封装调用结果(返回值、错误信息、状态)
  • JsonRpcProtocol: JSON-RPC 协议实现,支持跨语言调用

JSON协议格式:

// 请求格式
{
    "requestId": "unique-id",
    "interfaceName": "com.rpc.example.HelloService",
    "methodName": "sayHello",
    "paramTypes": ["string"],
    "parameters": ["World"]
}

// 响应格式
{
    "requestId": "unique-id",
    "success": true,
    "result": "Hello, World!",
    "errorMsg": ""
}

启用JSON协议服务端:

SocketServer server = new SocketServer();
server.setUseJsonProtocol(true);
server.register(new HelloServiceImpl(), HelloService.class.getName());
server.start(8888);

序列化模块 (serialization)

支持对象与字节流的相互转换:

  • Serializer: 序列化器接口
  • JsonSerializer: JSON 序列化实现
  • KryoSerializer: Kryo 二进制序列化(高性能)
  • HessianSerializer: Hessian 二进制序列化
  • ProtobufSerializer: Protobuf 序列化
  • SerializerFactory: 序列化器工厂
  • SerializerType: 序列化类型枚举

性能对比:

序列化器 性能 可读性 跨语言 推荐场景
JSON ⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ 调试/日志
Kryo ⭐⭐⭐⭐⭐ 生产环境
Hessian ⭐⭐⭐⭐⭐ ⭐⭐⭐ 生产环境
Protobuf ⭐⭐⭐⭐⭐ ⭐⭐ ⭐⭐⭐⭐⭐ 跨语言服务

IDL与跨语言模块 (idl)

自定义IDL语言,支持跨语言服务调用:

  • IdlCompiler: IDL编译器主类
  • Lexer: 词法分析器
  • Parser: 语法分析器
  • SemanticAnalyzer: 语义分析器
  • JavaGenerator: Java代码生成器
  • PythonGenerator: Python代码生成器(生成数据模型+RPC客户端)
  • GoGenerator: Go代码生成器(生成数据模型+RPC客户端)

IDL示例:

namespace com.rpc.example

// 定义数据结构
struct UserInfo {
    long id
    string username
    string email
    int age
}

// 定义服务接口
service UserService {
    UserInfo getUser(long userId)
    UserInfo createUser(string username, string email, int age)
    bool deleteUser(long userId)
    list<UserInfo> listUsers(int page, int pageSize)
}

编译生成:

# 生成Java代码
mvn exec:java "-Dexec.mainClass=com.rpc.idl.compiler.IdlCompiler" \
  "-Dexec.args=-i demo/demo0/idl/user_service.rpcl -o demo/demo0/generated -l java -p com.rpc.example"

# 生成Python代码
mvn exec:java "-Dexec.mainClass=com.rpc.idl.compiler.IdlCompiler" \
  "-Dexec.args=-i demo/demo0/idl/user_service.rpcl -o demo/demo0/generated -l python -p com.rpc.example"

# 生成Go代码
mvn exec:java "-Dexec.mainClass=com.rpc.idl.compiler.IdlCompiler" \
  "-Dexec.args=-i demo/demo0/idl/user_service.rpcl -o demo/demo0/generated -l go -p com.rpc.example"

生成的跨语言客户端文件:

语言 生成文件 说明
Python rpc_client.py RPC客户端基础类(连接管理、请求发送)
Python user_service_client.py UserService客户端实现
Go rpc_client.go RPC客户端基础类(连接管理、请求发送)
Go user_service_client.go UserService客户端实现

Python跨语言调用示例:

from com.rpc.example.service.rpc_client import RpcClient
from com.rpc.example.service.user_service_client import UserServiceClient

# 创建RPC客户端
rpc_client = RpcClient("localhost", 8888)
user_client = UserServiceClient(rpc_client)

# 调用远程服务
user = user_client.get_user(user_id=12345)
print(f"User: {user.username}, Email: {user.email}")

# 关闭连接
rpc_client.close()

Go跨语言调用示例:

import (
    "fmt"
    rpc "com.rpc.example/rpc"
    "com.rpc.example/service"
)

func main() {
    // 创建RPC客户端
    rpcClient := rpc.NewRpcClient("localhost", 8888, 30*time.Second)
    userClient := service.NewUserServiceClient(rpcClient)

    // 调用远程服务
    user, err := userClient.GetUser(context.Background(), 12345)
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    fmt.Printf("User: %s, Email: %s\n", user.Username, user.Email)

    // 关闭连接
    rpcClient.Close()
}

支持的数据类型:

类型 说明 示例
基础类型 int, long, float, double, string, bool int age
容器类型 list, map, set list<string> names
自定义结构体 用户定义的struct UserInfo user

注册中心模块 (registry)

提供服务注册与发现功能:

  • ServiceRegistry: 注册中心接口
  • LocalServiceRegistry: 本地内存注册中心(开发/测试用)
  • NacosServiceRegistry: Nacos 注册中心(生产环境)
  • ServiceRegistryFactory: 注册中心工厂

通信模块 (transport)

处理网络通信:

  • RpcServer: 服务端接口
  • SocketServer: Socket 服务端实现
  • RpcClient: 客户端接口
  • SocketClient: Socket 客户端实现
  • PooledSocketClient: 连接池客户端(长连接复用)
  • ConnectionPool: 连接池实现
  • RegistryAwareClient: 支持服务发现的客户端

代理模块 (proxy)

实现透明远程调用:

  • RpcClientProxy: JDK 动态代理,将本地调用转换为远程调用
  • 支持方法级超时配置
  • 内置重试机制(使用RetryStrategy接口)
  • 支持自定义RetryStrategy

重试模块 (retry)

提供重试策略支持:

  • RetryStrategy: 重试策略接口(定义退避延迟计算)
  • FixedRetryStrategy: 固定间隔重试
  • ExponentialBackoffRetryStrategy: 指数退避重试
  • RetryExecutor: 注解式重试执行器

负载均衡模块 (loadbalancer)

提供多种负载均衡策略:

  • LoadBalancer: 负载均衡器接口
  • LoadBalancerType: 负载均衡类型枚举
  • LoadBalancerFactory: 负载均衡器工厂
  • RandomLoadBalancer: 随机负载均衡
  • RoundRobinLoadBalancer: 轮询负载均衡
  • WeightedRoundRobinLoadBalancer: 加权轮询负载均衡

策略对比:

策略 Name 说明 适用场景
随机 random 随机选择服务实例 请求量小,实例少
轮询 roundRobin 循环选择服务实例 实例性能相近
加权轮询 weightedRoundRobin 根据权重比例分配 实例性能不均

配置模块 (config)

全局配置管理:

  • RpcConfig: RPC 全局配置类,支持 builder 模式

配置说明

使用 Nacos 注册中心

// 服务端
ServiceRegistry registry = ServiceRegistryFactory.createNacosRegistry("localhost:8848");
SocketServer server = new SocketServer(registry);
server.register(new HelloServiceImpl(), HelloService.class.getName());
server.start(8888);

// 客户端
ServiceRegistry registry = ServiceRegistryFactory.createNacosRegistry("localhost:8848");
RegistryAwareClient client = new RegistryAwareClient(registry);
HelloService helloService = RpcClientProxy.createProxy(HelloService.class, client);

使用多种序列化器

// 使用 Kryo 序列化
SocketClient client = new SocketClient("localhost", 9999, new KryoSerializer());

// 使用 Hessian 序列化
SocketServer server = new SocketServer();
server.setSerializer("hessian");

// 使用配置类
RpcConfig config = RpcConfig.builder()
    .serializer("kryo")
    .build();

使用连接池

PooledSocketClient client = new PooledSocketClient("localhost", 9999);
RpcClientProxy proxy = new RpcClientProxy(client, serviceName);
HelloService service = proxy.getProxy(HelloService.class);

// 连接自动复用
for (int i = 0; i < 100; i++) {
    service.sayHello("User" + i);
}

重试与超时配置

// 自定义重试参数
RpcClientProxy proxy = new RpcClientProxy(client, serviceName,
    5000,   // 默认超时5秒
    3,      // 最多重试3次
    1000);  // 基础退避间隔1秒

// 方法级超时配置
proxy.setMethodTimeout("fastMethod", 1000);   // 1秒超时
proxy.setMethodTimeout("slowMethod", 30000);  // 30秒超时

全局配置

RpcConfig config = RpcConfig.builder()
    .host("localhost")
    .port(9999)
    .connectionTimeout(5000)
    .readTimeout(10000)
    .serializer("kryo")
    .maxRetryAttempts(3)
    .retryBackoffMs(1000)
    .maxConnectionPoolSize(8)
    .build();

SocketClient client = new SocketClient("localhost", 9999, config);
RpcClientProxy proxy = new RpcClientProxy(client, serviceName, config);

负载均衡配置

// 方式1:使用默认随机策略
RegistryAwareClient client = new RegistryAwareClient(registry);

// 方式2:指定负载均衡策略
RegistryAwareClient client = new RegistryAwareClient(registry, "roundRobin");

// 方式3:自定义负载均衡器
LoadBalancer loadBalancer = new WeightedRoundRobinLoadBalancer();
RegistryAwareClient client = new RegistryAwareClient(registry, loadBalancer);

// 方式4:通过配置
RpcConfig config = RpcConfig.builder()
    .loadBalancer("weightedRoundRobin")
    .build();

带权重的服务注册

// 创建带权重的服务实例
ServiceInfo service1 = new ServiceInfo("HelloService", "192.168.1.1", 8080, 100);
ServiceInfo service2 = new ServiceInfo("HelloService", "192.168.1.2", 8080, 50);

// 注册服务
registry.register("HelloService", "192.168.1.1", 8080, 100);
registry.register("HelloService", "192.168.1.2", 8080, 50);

运行测试

# 运行所有测试
mvn test

# 运行集成测试
mvn test -Dtest=RpcIntegrationTest

# 运行注册中心测试
mvn test -Dtest=LocalServiceRegistryTest

文档

技术栈

  • Java 11
  • Maven
  • Jackson (JSON 序列化)
  • Nacos Client (服务注册发现)
  • JUnit 5 (单元测试)
  • SLF4J + Logback (日志)

许可证

MIT License

关于

分布式计算大作业——RPC框架的设计与实现

479.0 KB
邀请码
    Gitlink(确实开源)
  • 加入我们
  • 官网邮箱:gitlink@ccf.org.cn
  • QQ群
  • QQ群
  • 公众号
  • 公众号

版权所有:中国计算机学会技术支持:开源发展技术委员会
京ICP备13000930号-9 京公网安备 11010802047560号