1、概述
SylixOS中移植了SUN公司的开源RPC库——libsunrpc,主要用于远程过程调用,现对其通信机制及远程调用过程做简单的介绍。
2、RPC通信机制
2.1 RPC介绍
RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。
RPC采用客户机/服务器模式,请求程序就是一个客户机,而服务提供程序就是一个服务器。首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行。
2.2 调用分类
RPC调用分以下两种:
(1)同步调用:客户方等待调用执行完成并返回结果。
(2)异步调用:客户方调用后不用等待执行结果返回,但依然可以通过回调通知等方式获取返回结果。若客户方不关心调用返回结果,则变成单向异步调用,单向调用不用返回结果。
异步调用和同步调用的区分在于是否等待服务端执行完成并返回结果。
2.3 RPC调用过程
2.3.1 一次调用步骤
RPC一次远程调用的具体步骤如下图所示。
(1)客户调用一个称为客户程序存根(client stub)的本地过程,对客户来说,客户存根看起来就是它想要调用的真正的服务器过程。客户程序存根的作用在于把待传输给远程过程的参数打包,转换成某种标准格式,然后构造一个或多个网络消息。
(2)构造的网络消息由客户程序存根发送给远程系统,这通常需要进行系统调用(如write或sendto)。
(3)该步骤为网络消息传输过程,使用的典型网络传输协议为TCP或者UDP。
(4)远程系统上的服务器程序存根(server stub)一直在等待客户的请求,负责从接收到的网络消息中解析出客户的参数。
(5)服务器程序存根执行一个本地过程调用以激活真正的服务器函数,将上一步解析出的参数传入该服务器过程。
(6)当服务器过程完成时,它向服务器程序存根返回其运行结果。
(7)服务器程序存根对返回值进行转换,并将其构造成一个或多个网络消息,以便发送给客户。
(8)消息通过网络传送回客户端。
(9)客户程序存根从本地内核中读出网络消息(read或recvfrom)。
(10)客户程序存根对返回值进行必要的转换后,将结果返回给客户程序,这一步看起来就是一个普通的过程返回给客户。
2.3.2如何唯一确定远程过程
一个远程过程是由三要素来唯一确定:
(1) 程序号
(2) 版本号
(3) 过程号
程序号用来区别一组相关的并且具有唯一过程号的远程过程。一个程序可以有多个不同的版本,而每个版本的程序都包含一系列能被远程调用的过程,每个过程则有其唯一标识的过程号。
客户端与服务器端约定好某个远程过程的程序号、版本号和过程号。服务器程序存根根据程序号和版本号注册一个远程调用程序,该远程调用程序中再根据过程号去调用该远程过程;客户根据程序号和版本号调用RPC接口获取一个客户端句柄,然后调用句柄内保存的回调函数,传入客户主机的入参、远程过程号、返回值、数据格式转换回调函数等,最终实现调用一个唯一确定的远程过程。
2.4 服务器捆绑
客户端和服务器端建立网络连接时,客户端是如何发现服务器端的端口号的呢?首先我们需要注意的是,运行RPC服务器的任何主机必须先运行端口映射器,然后RPC服务器先绑定一个临时端口号,再向本地端口映射器注册该临时端口。当一个客户启动时,它必须先跟服务器主机上的端口映射器联系,询问服务器的临时端口号,然后再跟这个临时端口号上的服务器联系,建立网络连接。如下图所示。
2.5 RPC超时和重传策略
RPC的超时和重传策略中使用了两个超时值:
(1) 总超时(total timeout):一个客户等待其服务器的应答的总时间量,TCP和UDP都使用该值。
(2) 重试超时(retry timeout):只用于UDP, 是一个客户等待其服务器的应答期间每次重传请求的相隔时间。
因为TCP是一个可靠的协议,所以不需要重试超时,TCP请求流程如下图所示。如果服务器主机没有接收到客户的请求,客户的主机就会超时并重传该请求。当服务器主机接收到客户机的请求时,服务器主机会向客户主机确认收到本次请求。如果服务器的确认丢失,导致客户主机重传该请求,那么当服务器主机接收到这个重复的数据时,它将丢弃该数据,并再次发出一个确认。
有了可靠的协议后,可靠性(超时、重传、重复数据或重复确认的处理)就由传输层保障。由客户主机RPC层发出的一个请求将由服务器主机RPC层作为一个请求接收(如果该请求没有得到确认,那么客户主机将会得到错误提示),而不管网络层和传输层发生什么。
2.6 XDR(外部数据表示法)
使用RPC进行通信的不同主机,它们的数据格式可能不同。首先,数据类型可能有不同的大小;其次,各主机可能存在大小端字节序的差异,所以RPC使用外部数据表示法(XDR)来消除这些差异,将数据包装在独立于介质的结构中使得数据可以在异构的计算机系统中传输。从局部表示转换到XDR称为编码,从XDR转换到局部表示称为译码。SylixOS内核中的libsunrpc库中,在“/libsunrpc/sunrpc/rpc/xdr.h”中提供了用于数据格式转换的接口。