CSE_lecture5:Remote Procedure Call

Remote Procedure Call

RPC让文件系统变成远程,同时让远程服务器像运行在本地一样,相比于sockets api,RPC不必因为突然变成远程服务器而修改代码,即这个接口应当同时能访问本地和远程

为了不改应用的高层代码,将缺乏语义的共同部分打包成RPC stub

client stub做以下事情:发请求,接受响应,进行convert

server stub做以下事情:使用一个do forever不断接受请求,根据参数进行switch case,从而判断响应OK与否

其中message里面包括:

  • service id
  • service parameter
  • marshal/unmarshal: 即保证object以序列化的形式传输,从而替代指针,收到消息后根据规则进行反序列化

RPC request message包括:

  • Xid: 即transaction id,保证每个消息都有一个id,便于重发
  • call/reply
  • rpc version
  • program #: 调用哪个程序(库文件)
  • program version
  • procedure #: 调用哪个函数
  • auth staff
  • arguments: 需要序列化

RPC reply message包括以下部分:

  • Xid
  • call/reply
  • accepted?: 用于判定RPC version
  • auth staff
  • success?: 用于判定prog/proc
  • results: 需要序列化

binding用于寻找服务器,这是依靠服务注册实现的

how to pass the data between client & server?

参数传递充满挑战性:

  • 跨服务器无法pass by reference,因此需要转换成pointless
  • 大小端的问题
  • client和server的兼容性

为了表示数据,需要进行encoding,这一般不会是语言特化的

standard encoding有JSON, XML, CSV等等,好处是人类可读,缺点是可能有二义性、binary strings支持困难等等

而binary formats难以阅读,但更紧凑、更准确、性能更好

JSON每次传输时都要出现字段名,而Thrift和Protocol Buffers使用schema来将字段及其类型进行编号码,从而进行压缩

以Thrift为例:

压缩还可以进一步进行,需要将这些0去除,比如记录field tag的差值,将数字变为链表存储等等:

stub代码可以自动生成,这只需要头文件即可

marshal/unmarshal也有可能反而耗时,因此其适用于慢的网速,而网速快时反而不需要压缩(这里是说是否有必要利用marshal的压缩功能,对于指针参数,marshal是必要的)

when RPC meets failure

本地调用基本不会出错,但RPC却可能遇到各种各样的错误,而我们的目标为只需要一次调用,而现在有三种场景:

  • at-least-once: 反复retry即可
  • at-most-once: server记录Xid,出现retry时将过去的结果返回,但问题在于什么时候删除
  • exactly-once: 很困难

需要区分幂等性(idempotent)和非幂等性,幂等的操作反复执行结果是一致的,配合at-least-once可以实现exactly-once


CSE_lecture5:Remote Procedure Call
http://example.com/2025/10/02/CSE-lecture5-Remote-Procedure-Call/
作者
jietiDdd
发布于
2025年10月2日
许可协议