5月27日 23:23
什么是 RPC?RPC 的基本原理和工作流程是什么?
RPC 是什么?
RPC(Remote Procedure Call)让一个进程像调用本地函数一样调用远端进程的函数,调用方无需关心底层网络细节。简单说,你写 result = addUser(user) 的时候,addUser 可能跑在另一台机器上,但你代码看起来和本地调用没区别。
一次 RPC 调用经历了什么?
以调用 userServer.getUser(id) 为例:
- 客户端调用 Stub:调用方发起调用,实际先到客户端存根(Stub),Stub 负责把方法名、参数打包
- 序列化:将参数对象转成二进制流(如 Protobuf、Hessian),这是"编组"过程
- 网络传输:二进制数据通过 TCP/HTTP2 发往服务端,gRPC 默认走 HTTP/2
- 服务端反序列化:Skeleton 接收数据,还原出方法名和参数
- 执行本地方法:服务端找到真实实现类执行,拿到返回值
- 结果序列化回传:返回值同样序列化后走网络回客户端
- 客户端反序列化:Stub 把二进制还原成结果对象,返回给调用方
整个过程对业务代码透明,网络通信、序列化、寻址全部由框架处理。
核心组件
- Stub/Skeleton:客户端和服务端的代理层,屏蔽网络细节
- 序列化协议:Protobuf 体积最小性能最好,JSON 通用但空间开销大,Hessian 折中
- 传输协议:TCP 直连延迟最低,HTTP/2 支持多路复用,gRPC 底层用 HTTP/2 + Protobuf
- 注册中心:服务端注册地址,客户端从注册中心发现服务(Consul、Etcd、Nacos)
为什么不直接用 HTTP?
HTTP 1.1 是文本协议,头部冗余大,每次请求都要建连接;RPC 框架通常基于长连接 + 自定义二进制协议,序列化体积小、连接复用,吞吐量高出一个量级。当然 gRPC 基于 HTTP/2 也能兼顾性能和通用性,具体选型看场景。
常见追问
RPC 和本地调用有什么区别?
本地调用可靠且零延迟;RPC 存在网络抖动、超时、服务不可用等问题,需要重试、熔断、降级等容错机制。
序列化怎么选?
对性能敏感选 Protobuf,跨语言交互且可读性优先选 JSON,Java 体系内 Dubbo 默认 Hessian 也够用。
服务挂了怎么办?
注册中心心跳检测摘除异常节点,客户端侧配合熔断器(如 Sentinel)快速失败,避免级联雪崩。