大多数程序员都用过 Dubbo、gRPC、Spring Cloud 等成熟框架。但你是否想过:RPC 的本质到底是什么?
本文带你从零手撕一个具备通信、注册、负载均衡、限流熔断、监控告警、CI/CD 等完整能力的 RPC 框架,真正搞懂它的原理、设计思路和可落地的工程实现。
什么是 RPC?
orderService.createOrder(order);
你以为调用的是本地方法,其实请求已经通过网络,发到了远程机器上。
我们要实现一个什么样的 RPC 框架?
目标:打造一个高可用、模块化、具备生产级能力的轻量 RPC 框架:
特性包括:
基于 Netty 的通信能力
支持自定义协议编解码
支持服务注册与发现
支持多种负载均衡策略
实现限流熔断机制
实现调用链追踪(TraceId)
集成 Prometheus 监控 & 告警
支持 GitHub Actions + Docker + K8s 的 CI/CD
最终,你将收获一套真实可用、具备核心治理能力的 RPC 框架,并搞懂它的每一层实现原理。
一、框架架构总览
┌────────────┐ ┌────────────┐
│ Consumer │─────│ Provider │
└────────────┘ └────────────┘
│ │
▼ ▼
┌────────────────────────────────────┐
│ 通信层(Netty) │
│ 编解码层(自定义协议) │
│ 注册中心(ZK/Nacos) │
│ 路由负载均衡(轮询/Hash) │
│ 服务治理(限流、熔断、重试) │
│ 监控链路追踪(TraceId + Prom) │
└────────────────────────────────────┘
二、从底层开始:通信协议 & 编解码
我们设计一套简单的协议:
魔数 + 版本 + 消息类型 + 请求ID + 数据长度 + 请求体
使用 Netty 实现通信:
// 编解码器
class MessageEncoder extends MessageToByteEncoder<RpcRequest> { ... }
class MessageDecoder extends ByteToMessageDecoder { ... }
// Netty 服务端/客户端
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.childHandler(new ChannelInitializer<>() { ... });
支持心跳包、超时机制、自定义序列化(JSON / Protobuf)。
三、注册中心:服务注册 & 发现
我们用 Zookeeper 实现一个简单的服务注册中心:
/rpc-services/OrderService/providers/ip:port
- Provider 启动时向 ZK 注册临时节点
- Consumer 启动时订阅节点变化,动态维护 Provider 列表
可封装:
interface RegistryService {
void register(String serviceName, String ip, int port);
List<Endpoint> discover(String serviceName);
}
四、负载均衡策略
支持策略:
- 轮询(RoundRobin)
- 随机(Random)
- 一致性哈希(ConsistentHash)
- 最少连接数(LeastActive)
public interface LoadBalancer {
Endpoint select(List<Endpoint> endpoints);
}
五、服务治理:限流 + 熔断 + 重试
限流(令牌桶算法)
class TokenBucketLimiter {
int capacity = 100;
AtomicInteger tokens = new AtomicInteger(capacity);
...
}
熔断器状态图
CLOSED ——→ OPEN ——→ HALF-OPEN ——→ CLOSED
六、链路追踪 & 调用监控
每次 RPC 请求打上唯一 TraceId:
ThreadLocalContext.set("traceId", UUID.randomUUID().toString());
日志中统一打印:
[traceId=abc123] 调用 OrderService 耗时 48ms 成功
监控系统使用 Micrometer + Prometheus:
- QPS
- RT(响应时间)
- 错误率
- 在线 Provider 数量
结合 Grafana 做可视化展示。
七、CI/CD:从构建到部署
构建方式
- 使用 GitHub Actions 编译 + 打包 + Docker 镜像
- Docker 镜像推送到 Registry(如 Aliyun、Harbor)
- 使用 Helm 部署到 Kubernetes 集群
示例流程:
- name: Build
run: mvn clean package
- name: Docker Build
run: docker build -t my-rpc-service .
- name: Push to Registry
run: docker push my-rpc-service
- name: Deploy to K8s
run: helm upgrade --install ...
八、告警系统接入
- Prometheus + AlertManager 设置告警规则
- 支持钉钉 / 飞书 / 邮件 Webhook
- 典型告警场景:
- Provider 数量变为 0
- 错误率超过 10%
- 响应延迟高于 500ms
九、一套完整使用示例(业务开发者视角)
服务提供者:
@RpcService
public class OrderServiceImpl implements OrderService {
public void createOrder(Order order) {
...
}
}
服务消费者:
@RpcReference
private OrderService orderService;
orderService.createOrder(order); // 框架自动路由 + 远程调用
十、总结
模块 | 状态 | 技术 |
通信层 | 完成 | Netty |
编解码 | 完成 | Protobuf |
注册发现 | 完成 | Zookeeper |
负载均衡 | 多策略 | Hash、轮询 |
熔断限流 | 支持 | 自研限流器、熔断器 |
调用链追踪 | 完成 | TraceId |
监控告警 | 接入 | Prometheus + Grafana |
CI/CD 自动部署 | 集成 | GitHub Actions + Docker |
最后
写这个 RPC 框架不是为了“造轮子”,而是:
了解分布式通信的本质
训练系统设计能力
拥有架构思维
打开深入中间件开发的大门