Zenghui Bao's World

about life, programming, misc thoughts.

RPC优缺点

最近在阅读一些开源代码,看到好多项目是用RPC方式(而不是直接用消息传递)来进行模块间的通信,遂思考了下RPC的优缺点。

优点

  1. 交互方式简单,一个service就是一个interface。client/server间的交互协议容易统一。
    一般成熟的公司都自己维护的RPC框架(比如百度的sofa-pbrpc, google的gRpc,使用它们非常简单,只需要一个proto文件就可以描述两边的协议交互。因为描述文件(proto文件)是确定的,所以两边容易保持一致,基本不会出错。而且大多可用RPC框架生成所有interface的封包、解包代码,用户只需要调调函数即可。

  2. 测试方便。
    大多RPC框架是跨语言的,所以可用更方便的脚本语言(如python)写测试程序,模拟与C/C++程序的交互。

缺点

  1. 多了一层间接性,出现网络问题时,debug比较困难。

  2. 交互方式单一,不能进行复杂的多模块之间的协议交互。
    RPC的描述方式较单一,一般是一应一答。有一些场景没法用RPC描述,比如有一个服务需要协调多个模块、服务端主动发通知给客户端。

  3. 异常处理困难。

    • 如果是同步调用,长时间阻塞怎么办?
    • 如果是异步调用,长时间没有得到结果怎么办?
    • 如果判断failure(网络不通、参数不对、心跳超时)?
      可以重试吗?调用语意:至多一次、至少一次、恰好一次?

一般RPC执行的结果有三种状态:成功、失败、超时(未知状态)。当发生超时时,不知道对端server是收到请求且已经执行了,还是没收到请求,此时只能通过不断读取之前操作的状态来验证RPC操作是否成功,然后采取相应的操作。但是如果每次调用RPC都要做各种各样的异常处理,代码会不会变得冗长哆嗦?

还有一种处理方法是将操作设计成一种”幂等”操作,就是说,执行多次与执行一次的结果是一样的,比如说覆盖写操作。但是某些客户操作不方便表示成幂等操作,这时候应该怎么处理呢?


##参考

分布式系统的工程化开发方法