IPC 和 RPC 经常一起出现,但它们解决的不是同一个问题。
最简单的区分是:
IPC 解决进程之间怎么传数据,RPC 解决怎样把数据交换包装成一次函数调用。
IPC:进程间通信
IPC 是 Inter-Process Communication,也就是进程间通信。
不同进程拥有各自独立的内存,不能直接读取对方的变量。它们要交换数据,需要借助操作系统提供的通信机制,例如:
- Unix Domain Socket
- 匿名管道、命名管道
- 共享内存
- 消息队列
IPC 关心的是:
text
一段数据怎样从进程 A 到达进程 B?
它通常不关心数据表达的是查询、写入,还是一次业务操作。
RPC:远程过程调用
RPC 是 Remote Procedure Call,也就是远程过程调用。这里的"远程"不一定是另一台机器,也可以是本机的另一个进程。
RPC 会把底层通信包装成类似函数调用的形式:
js
const user = await userService.getUser(42);
底层实际发生的过程通常是:
- 客户端生成请求 ID;
- 序列化方法名和参数;
- 通过 IPC 或网络发送请求;
- 服务端找到对应方法并执行;
- 服务端返回结果或错误;
- 客户端根据请求 ID 找到对应调用。
例如,一条 JSON-RPC 请求可能是:
json
{
"jsonrpc": "2.0",
"id": 1,
"method": "getUser",
"params": { "id": 42 }
}
两者是什么关系?
RPC 通常运行在某种 IPC 或网络通道之上。
text
RPC 方法调用
↓
序列化和消息分帧
↓
IPC 或网络通道
↓
另一个进程或服务
假设两个本机进程通过 Unix Domain Socket 传输 JSON-RPC 消息:
- 从传输角度看,它使用了 IPC;
- 从调用语义看,它进行的是 RPC。
这两种说法都对,只是描述的层次不同。
可以把它们类比为:
text
IPC = 公路
RPC = 公路上运行的快递系统
公路负责把东西运过去;快递系统还定义收件人、运单号、交付结果和异常处理。
服务之间的通信都是 RPC 吗?
不是。
同步的请求---响应调用通常具有 RPC 语义,但服务之间还可以通过其他方式通信:
- 消息队列
- 发布订阅
- 事件通知
- 持续数据流
这些方式不一定要求调用某个明确的方法,也不一定等待对应的返回值。
RPC 不等于本地函数调用
RPC 看起来像函数调用,但它还会遇到本地调用没有的问题:
- 请求超时;
- 连接中断;
- 服务不可用;
- 请求已经执行,但响应丢失;
- 重试导致重复执行。
因此设计 RPC 接口时,除了方法和参数,还要考虑超时、重试、幂等、取消和鉴权。
总结
只要记住两句话:
IPC 描述数据怎么在进程之间传输。
RPC 描述如何把这次数据交换组织成方法调用。
Unix Domain Socket、Pipe 属于 IPC 手段 ;JSON-RPC、gRPC 属于 RPC 方案。RPC 可以建立在 IPC 之上,两者并不冲突。