客户端-服务器应用程序的通用机制由 远程过程调用 (RPC) 包提供。RPC 由 Sun Microsystems 开发,是一系列工具和库函数的集合。基于 RPC 构建的重要应用程序包括 NIS,网络信息系统(在第 13 章中描述)和 NFS,网络文件系统(在第 14 章中描述),这两者都在本书中进行了描述。
RPC 服务器由一系列过程组成,客户端可以通过向服务器发送 RPC 请求以及过程参数来调用这些过程。服务器将代表客户端调用指示的过程,并返回返回值(如果有)。为了实现机器独立性,客户端和服务器之间交换的所有数据都由发送者转换为 外部数据表示 格式 (XDR),并由接收者转换回机器本地表示。RPC 依赖于标准的 UDP 和 TCP 套接字来将 XDR 格式的数据传输到远程主机。Sun 慷慨地将 RPC 置于公共领域;它在一系列 RFC 中进行了描述。
有时,对 RPC 应用程序的改进会在过程调用接口中引入不兼容的更改。当然,仅仅更改服务器会使所有仍然期望原始行为的应用程序崩溃。因此,RPC 程序被分配了版本号,通常从 1 开始,并且随着 RPC 接口的每个新版本,此计数器都会递增。通常,服务器可能会同时提供多个版本;然后,客户端通过其请求中的版本号来指示他们想要使用的服务实现。
RPC 服务器和客户端之间的通信有点特殊。一个 RPC 服务器提供一个或多个过程集合;每个集合都称为一个 程序,并通过一个 程序号 唯一标识。服务名称到程序号的映射列表通常保存在/etc/rpc中,其摘录显示在 示例 12-4 中。
示例 12-4。/etc/rpc 文件示例
# # /etc/rpc - miscellaneous RPC-based services # portmapper 100000 portmap sunrpc rstatd 100001 rstat rstat_svc rup perfmeter rusersd 100002 rusers nfs 100003 nfsprog ypserv 100004 ypprog mountd 100005 mount showmount ypbind 100007 walld 100008 rwall shutdown yppasswdd 100009 yppasswd bootparam 100026 ypupdated 100028 ypupdate |
在 TCP/IP 网络中,RPC 的作者面临着将程序号映射到通用网络服务的问题。他们设计每个服务器为每个程序和每个版本提供 TCP 和 UDP 端口。通常,RPC 应用程序在发送数据时使用 UDP,只有当要传输的数据不适合单个 UDP 数据报时才回退到 TCP。
当然,客户端程序需要找出程序号映射到哪个端口。为此使用配置文件将过于不灵活;由于 RPC 应用程序不使用保留端口,因此无法保证最初打算由我们的数据库应用程序使用的端口没有被其他进程占用。因此,RPC 应用程序选择它们可以获得的任何端口,并将其注册到一个名为 端口映射器守护进程 的特殊程序中。端口映射器充当在其机器上运行的所有 RPC 服务器的服务代理。希望联系具有给定程序号的服务的客户端首先查询服务器主机上的端口映射器,端口映射器将返回可以访问该服务的 TCP 和 UDP 端口号。
这种方法引入了单点故障,就像 inetd 守护进程对标准 Berkeley 服务所做的那样。但是,这种情况甚至更糟,因为当端口映射器死掉时,所有 RPC 端口信息都会丢失;这通常意味着您必须手动重启所有 RPC 服务器或重启整个机器。
在 Linux 上,端口映射器被称为/sbin/portmap,或者有时/usr/sbin/rpc.portmap。除了确保它从您的网络启动脚本启动之外,端口映射器不需要任何配置。