Skip to content

RPC 与服务通信

分布式系统里,一个绕不开的问题就是:服务和服务之间到底怎么通信。

表面上看,这只是“发请求”的问题。

但在企业系统里,真正的问题远不止于此,还包括:

  1. 用什么协议
  2. 如何序列化
  3. 如何发现目标服务
  4. 如何处理超时、重试、熔断
  5. 如何做接口治理和版本演进

这篇文章重点讲:

  1. RPC 到底是什么
  2. 它和 HTTP / REST 的关系是什么
  3. 为什么服务通信是分布式的基础能力
  4. 企业里常见选型长什么样
  5. 服务通信真正的工程难点是什么

1. RPC 到底是什么

RPCRemote Procedure Call,即远程过程调用。

它可以看成 让调用远程服务这件事,在编程模型上尽量接近调用本地方法

但一定要记住:它看起来像本地方法,不代表它真的是本地调用。

因为远程调用天然带着:

  1. 网络延迟
  2. 网络失败
  3. 序列化开销
  4. 超时和重试

2. 为什么服务通信是分布式基础能力

因为只要系统拆成多个服务,就一定会遇到:

  1. 用户服务调用订单服务
  2. 订单服务调用库存服务
  3. 支付服务调用账户服务

也就是说:服务一旦拆开,调用链就天然跨了进程甚至跨了机器。

所以服务通信不是“锦上添花”,而是分布式系统能不能运转起来的基本前提。


3. RPC 和 HTTP / REST 是什么关系

这也是最容易混的地方。

更具体一点:

  1. RPC 是调用模型
  2. HTTP 是传输协议之一
  3. REST 是一种接口设计风格

所以它们不是同一层概念。

你完全可以:

  1. 用 HTTP 实现 RPC 风格调用
  2. 用专门协议做 RPC
  3. 用 REST 风格暴露服务接口

4. 企业里常见的服务通信方式有哪些

通常可以分成两大类:

4.1 同步调用

调用方发请求,等待对方返回结果。

常见方式包括:

  1. HTTP / REST
  2. RPC 框架调用

4.2 异步通信

调用方把消息发出去,不同步等待对方立即完成。

常见方式包括:

  1. 消息队列
  2. 事件驱动

所以更具体一点:服务通信不只是一种协议问题,还包括同步与异步的架构选择。


5. 为什么很多公司会同时存在 HTTP 和 RPC

因为它们适合的场景并不完全一样。

5.1 HTTP / REST

更适合:

  1. 对外开放接口
  2. 跨语言调用
  3. 调试和排查方便

5.2 RPC

更适合:

  1. 内部服务高频调用
  2. 更强调接口契约和调用效率
  3. 更统一的服务治理

所以很多企业系统的实际形态往往是:

  1. 对外 API 更偏 HTTP / REST
  2. 内部服务调用更偏 RPC 或声明式 HTTP 调用

6. 服务通信里最常见的问题是什么

很多人会先想到协议,其实真正麻烦的常常是这些:

  1. 调用超时
  2. 重试放大问题
  3. 下游雪崩
  4. 版本兼容
  5. 请求链追踪困难

所以企业里真正的服务通信设计,不是“能调通就行”,而是:要把失败、超时和演进一起设计进去。


7. 一个最简单的声明式调用示例

以 Spring 生态里很常见的声明式 HTTP 调用为例:

java
@FeignClient(name = "stock-service")
public interface StockClient {

    @PostMapping("/stocks/deduct")
    void deduct(@RequestBody DeductStockRequest request);
}

业务侧:

java
@Service
public class OrderService {

    private final StockClient stockClient;

    public OrderService(StockClient stockClient) {
        this.stockClient = stockClient;
    }

    public void createOrder(CreateOrderCommand command) {
        stockClient.deduct(new DeductStockRequest(command.getProductId(), command.getCount()));
    }
}

这个例子本质上想表达的是:服务调用的关键价值,是把跨进程调用组织成可维护的接口模型。


8. 服务通信为什么要强调超时、重试和熔断

因为分布式调用链一长,任何一个下游抖动都可能把上游拖慢。

例如:

  1. 库存服务响应慢
  2. 订单服务线程一直等
  3. 网关请求不断堆积
  4. 最后整条链路雪崩

所以服务通信里必须认真处理:

  1. 超时控制
  2. 重试策略
  3. 熔断与降级
  4. 限流和隔离

这也说明:通信协议只是起点,治理能力才是通信真正能落地的保障。


9. 接口契约为什么也属于服务通信问题

服务一旦拆分,接口契约就成了跨团队协作边界。

这意味着你不仅要关心:

  1. 参数传什么
  2. 返回什么

还要关心:

  1. 字段能不能删
  2. 版本怎么升级
  3. 错误码怎么统一
  4. 是否向后兼容

所以企业里服务通信的另一条主线其实是:接口契约治理。


10. 工程上最容易混的几个边界

10.1 误区一:RPC 比 HTTP 高级,所以应该全面替换

不是。

选择取决于调用场景、团队技术栈和治理需求。

10.2 误区二:看起来像本地方法,就可以按本地方法心态写

这是非常危险的。

远程调用永远要考虑失败、超时和重试。

10.3 误区三:只要接口调通,通信层就没问题

真正的问题往往出在高峰期、故障期和版本演进期。


11. 一句话总结

RPC 与服务通信这条线,本质上是在解决分布式系统里服务如何稳定、清晰、可治理地互相调用;而企业里真正的难点,不只是协议选型,而是如何把超时、重试、兼容性和治理能力一起设计进去。

基于 VitePress 构建的个人技术笔记。