RPC 框架
趣谈网络协议---RPC协议综述:远在天边,近在眼前-LMLPHP

  • 客户端的应用发起一个远程调用时,实际是通过本地调用 Stub。Stub 负责将调用的接口、方法和参数,通过约定的协议规范进行编码,并通过本地的 RPCRuntime 进行传输,将网络包发送到服务器。

  • 服务器的 RPCRuntime 收到请求,交给提供方 Stub 解码,然后调用服务端的方法,服务端执行方法,返回结果。提供方 Stub 将结果编码,发送各客户端。

  • 客户端的 RPCRuntime 收到结果,发给调用方 Stub 解码,返回给客户端。

RPC 实现

Sun 公司是第一个提供商业化 RPC 库和 RPC 编译器的公司,其 RPC 框架在 NFS(Network File System,网络文件系统)协议中使用。
趣谈网络协议---RPC协议综述:远在天边,近在眼前-LMLPHP
NFS 运行时,启动两个服务端:

  • mountd,挂载文件路径,将一个远程的目录 mount 到本地目录。
  • nfsd,读写文件,在挂载的目录中写入、读出任何文件时,其实操作的是远程另一台机器上的文件。

RPC 的底层是 Socket。

RPC 调用过程中,所有数据类型都要封装成 XDR 格式。XDR(External Data Representation,外部数据表示法)是一个标准的数据压缩格式,可以表示基本的数据类型,也可表示结构体。

XDR 数据类型:
趣谈网络协议---RPC协议综述:远在天边,近在眼前-LMLPHP

RPC 的调用和结果返回的格式:
趣谈网络协议---RPC协议综述:远在天边,近在眼前-LMLPHP

  • XID 唯一标识一对请求和回复,请求为 0,回复为 1。
  • RPC 有版本号,两端不匹配 RPC 版本号,返回 Deny,原因为 RPC_MISMATCH。
  • 程序有编号,找不到该程序,返回 PROG_UNAVALI。
  • 程序有版本号,版本号不匹配,返回 PROG_MISMATCH。
  • 程序中有多个方法,方法有编号,找不到则返回 PROC_UNAVAIL。
  • 调用需要认证授权,不通过则 Deny。
  • 参数列表,无法解析则返回 GABAGE_ARGS。

客户端和服务端在实现 RPC 时,首先要定义一个双方都认可的程序、版本、方法、参数等。
趣谈网络协议---RPC协议综述:远在天边,近在眼前-LMLPHP
图中,对于加法函数,双方约定一个协议定义文件,同理,如果时 NFS、mount 和读写,也会有类似定义。

ONC RPC 会提供一个工具,根据协议定义文件生成客户端和服务端的 Stub 程序。
趣谈网络协议---RPC协议综述:远在天边,近在眼前-LMLPHP
最下层为 XDR 文件,对参数进行编码和解码。

客户端调用 clnt_create 创建一个连接,然后调用 add_1(Stub 函数),如同本地调用,该函数发起 RPC 调用,通过调用 clnt_call 调用 ONC RPC 类库发送真正的请求。

服务端 Stub 监听客户请求,如果是 add,调用真正的服务端逻辑,即将两数相加。

服务端将结果返回服务端 Stub,Stub 将结果发送给客户端,客户端 Stub 将结果返回给客户端应用程序。

传输问题

错误、重传、丢包、性能等问题,由 ONC RPC 类库解决。

为解决传输问题,对于每个客户端,都会创建一个传输管理层,会有队列机制、拥塞窗口机制等。

网络传输时,经常需要等待,同步方式效率较低,为了能异步处理,往往通过状态机实现远程调用。不满足状态时,不等,而是将资源留出,供其他 RPC 调用。

趣谈网络协议---RPC协议综述:远在天边,近在眼前-LMLPHP

  • 进入起始状态,查看 RPC 的传输队列中是否满,如果队列满,则直接结束或重试;否则,申请成功,可分配内存,获取服务的端口号,连接服务器。
  • 连接成功,发送 RPC 请求,等待获取 RPC 结果;发送出错,可重新发送;连接断开,可重新连接;超时,可重新传输;获取到结果,则解码,正常结束。

服务发现问题

在 ONC RPC 中,服务发现通过 portmapper 实现。

趣谈网络协议---RPC协议综述:远在天边,近在眼前-LMLPHP

portmapper 在一个众所周知的端口上启动。RPC 程序启动时,向 portmapper 注册自己的端口。客户端要访问 RPC 服务端时,先查询 protmapper,获取 RPC 服务端的端口,然后向该端口建立连接,开始 RPC 调用。图中为 mount 命令的 RPC 调用实现。

10-02 19:09