Linux 网络编程,第 3 部分

作者:Ivan Griffin

在本系列的最后几篇文章中,我们讨论了 Linux 中的基本底层网络编程,以及开发网络服务器(守护进程)所涉及的问题。然而,在这种底层级别上进行编码非常繁琐,并且很容易出错。

尽管如此,通过网络分发应用程序比单体、独立的结构提供了显著的优势——这些优势使得额外的开发投入(在时间和金钱方面)是值得的。

在本文中,我们将介绍一种旨在通过将面向对象的技术应用于开发和编码来减少编写网络应用程序时增加的复杂性的方法——即使用 通用对象请求代理体系结构 (CORBA)。

在下一篇文章中,我们将介绍可用于 Linux 的、实现 CORBA 标准的不同软件包。此外,还将对使用 CORBA 开发应用程序进行基本介绍。

请注意,本文假设读者对 C、C++、面向对象开发、BSD 套接字 API 和 RPC 有基本的了解。它介绍了在开发应用程序之前需要理解的 CORBA 的关键概念。这些概念以及相关的术语构成了 CORBA 的大部分学习曲线。本文必然是理论性的,以便建立一个在用 CORBA 开发时使用的词汇表。

分布式计算的优势

将系统构建为一组分布式组件的动机包括:

  • 通过更好的连接性和网络连接来增强协作能力

  • 通过使用并行处理来提高性能和效率的潜力

  • 通过复制来提高可靠性、可扩展性和可用性

  • 通过共享计算资源(例如,打印机、磁盘和处理能力)以及实施异构、开放系统来提高成本效益

伴随着这些令人印象深刻的优势,开发过程的复杂性也随之增加。程序员现在必须处理以下情况:

  • 网络延迟和等待时间

  • 系统中不同处理元素之间的负载均衡

  • 确保事件的正确排序

  • 通信链路的部分故障,特别是关于不可变事务(即,如果重复事务必须产生相同的结果——例如,银行交易的意外处理两次不应错误地影响账户余额)

减少程序员工作量(以开发这些分布式应用程序)的早期技术之一是远程过程调用 (RPC)。

远程过程调用

RPC 已在 Ed Petron 于 1997 年 10 月在Linux Journal 上发表的优秀文章“使用 /rdb 的便携式数据库管理”中介绍过。RPC 背后的动机是使网络编程像进行传统的函数调用一样容易。Linux 提供了开放网络计算风格的远程过程调用 (ONC-RPC),它最初由 Sun Microsystems(加利福尼亚州山景城)开发,用于其网络文件系统 (NFS) 实现。

RPC 所做的只是隐藏创建套接字(网络端点)、发送数据和根据需要关闭套接字的实现细节。它们还负责将(远程)过程的(本地数据)参数转换为适合网络传输的格式,并再次转换为可在远程主机上使用的格式。这种网络透明的数据传输确保了两端机器都可以正确解释信息内容。

通常,此过程中涉及不同的表示问题(例如,字节顺序、ASCII 到 EBCDIC 等)。此外,指针(对虚拟内存空间中地址位置的引用)不能直接从一个进程/机器传递到另一个进程/机器。相反,需要执行“深拷贝”,复制指针指向的数据,然后将其“跨线”发送。将数据从机器的本机格式传输到网络透明格式的整个过程称为“编组”。反向过程称为“解组”。ONC-RPC 使用一种称为外部数据表示 (XDR) 的特殊类型的编组。图 1 显示了远程过程调用中涉及的事件序列。RFC 1831、RFC 1832 和 RFC 1833 更详细地讨论了 ONC-RPC 的机制和语义。

图 1. 远程过程调用 (RPC)

面向对象的方法

如前所述,RPC 遵循传统的功能模型。状态信息可能需要在客户端和服务器端独立维护(取决于应用程序的类型)。此数据通常在每次远程函数调用时通过网络重复重新传输。

另一种架构是使用面向对象开发的技术,并将系统划分为一组独立的对象。每个对象负责维护自己的内部状态信息。

通过在网络软件开发中使用面向对象的方法,您可以促进代码中的某些有益特性:

  • 封装:确保系统中的对象相互交互的接口与其实现之间有清晰的分离

  • 模块化、可扩展性和可扩展性

  • 可重用性(代码的可重用性,也许更重要的是,设计的可重用性)

  • 功能和多态性的继承和专门化

从网络上的一个实体向另一个实体发送消息的行为与一个对象调用另一个对象上的方法非常相似。分布式网络技术和面向对象的集成将基本通信基础设施的特性与这些接口的高级抽象以及封装和模块化的框架结合在一起——通过这种方式,开发可互操作的应用程序更加直观。

对象管理体系结构

1991 年,一群有兴趣的各方联合起来成立了对象管理组 (OMG)——一个致力于分布式对象计算标准化的联盟。OMG 在其体系结构中支持异构性,为以任何语言编写的应用程序(在任何操作系统、任何硬件平台上运行)提供相互通信和协作的机制——本质上,开发一个“软件总线”以允许实现多样性,就像硬件总线对扩展卡所做的那样。

OMG 允许对象进行分布式协作的体系结构称为 对象管理体系结构 (OMA)。图 2 显示了对象管理体系结构。

图 2. 对象管理体系结构 (OMA)

CORBAservices 为对象在其生命周期内的管理提供基本功能——例如,这包括:

  • 命名(唯一指定特定的对象实例)

  • 安全(提供审计、身份验证等)

  • 持久性(允许将对象实例“展平”为字节序列或从字节序列创建)

  • 交易(为对象和 ORB 提供“广告”特定功能的机制)

  • 事件(允许对象动态注册或取消注册对特定类型事件的兴趣,本质上将通信与对象解耦)

  • 生命周期(允许创建、复制、移动、删除对象)

公共设施 提供使用分布式对象进行应用程序开发所需的框架。这些框架分为两个不同的组:水平设施(通常在所有应用程序中使用,例如用户界面管理、信息管理、任务管理和系统管理)和垂直设施(更与特定行业相关,例如电信或医疗保健)。

CORBA 标准指定了一个称为对象请求代理 (ORB) 的实体,它是将对象绑定在一起以实现更高级别分布式协作的“粘合剂”。它支持本地和远程对象之间 CORBA 请求的交换。图 3 显示了 CORBA 的体系结构。图 4 显示了通过 ORB 调用不同远程对象上的方法。

图 3. 通用对象请求代理体系结构 (CORBA)

图 4. 在特定对象实例中调用方法

关于 CORBA 的更多信息

在 OMA 中,对象提供服务。客户端向不同的对象发出请求,以代表他们执行这些服务。由于每个对象都负责维护自己的状态,因此避免了 RPC 应用程序常见的状态信息重复传输。此外,对象通过明确定义的接口进行交互,并且不了解彼此的实现细节。因此,只要接口得到维护,就更容易替换或升级对象实现。OMA/CORBA 系统中的对象可能彼此之间承担许多不同的角色:对等、客户端/服务器或发布/订阅等。

在对象可以发出请求以调用对象上的方法之前,它必须具有该对象的有效引用。ORB 使用此引用来识别和定位对象——从而提供位置透明性。作为应用程序编写者,您无需担心应用程序如何查找对象,ORB 会为您透明地执行此功能。与 RPC 如何使用 XDR 类似,CORBA 指定 通用数据表示 (CDR) 格式以跨网络传输数据。

对象引用不描述对象的接口。在应用程序可以使用对象(引用)之前,它必须以某种方式确定/知道对象提供哪些服务。

对象的接口通过 接口描述语言 (IDL) 定义。OMG IDL 通过它们支持的各种方法以及这些方法接受的参数来定义对象的接口。存在 IDL 的各种语言映射(例如,C、C++、Java、COBOL 等)。生成的语言存根为应用程序提供编译时知识,从而允许访问这些接口。

或者,可以将接口添加到一个特殊的数据库中,称为 接口存储库。接口存储库包含对象接口信息的动态副本,该副本是通过 IDL 静态生成的。动态调用接口 (DII) 是一种工具,对象客户端可以通过该工具探测对象以了解它支持的方法,并在发现特定方法后,可以在运行时调用它。这涉及查找对象接口,生成方法参数,在远程对象上调用方法并返回结果。

在“服务器”端,动态骨架接口 (DSI) 允许 ORB 调用那些不具有对象类型静态(即编译时)知识的对象实现。对特定对象的所有请求都通过让 ORB 调用同一个单次调用例程来处理,该例程称为 动态接口例程 (DIR)。实现存储库(与接口存储库相对)是一个关于 ORB 知道的类、其实例化对象和其他实现信息(日志记录、安全审计等)的运行时数据库。

对象适配器位于核心 ORB 网络功能之上。它充当 ORB 和对象之间的中介,代表对象接受方法请求。它有助于减轻“臃肿”的对象或 ORB。

对象适配器允许实例化新对象、ORB 和对象之间传递请求、将对象引用分配给对象(唯一命名对象)以及向实现存储库注册对象类。

目前,所有 ORB 实现都必须支持一个对象适配器,即 基本对象适配器 (BOA)。

除非来自不同开发人员/供应商的 ORB 可以相互通信,否则所有关于互操作性的讨论都是没有用的。通用 InterORB 协议 (GIOP) 是一个桥梁,它指定了用于 ORB 网络连接的标准传输语法和一组消息格式。GIOP 独立于任何网络传输。

Internet InterORB 协议 (IIOP) 指定了 GIOP 和 TCP/IP 之间的映射。也就是说,它详细说明了如何使用 TCP/IP 连接交换 GIOP 信息。通过这种方式,它实现了与基于世界上最流行的产品和供应商中立的网络传输——TCP/IP 的 IIOP 兼容 ORB 的“开箱即用”互操作性。

多层网络计算

CORBA 是所谓的“中间件”的一个例子——一种使应用程序能够分离为三个不同部分的技术(见图 5):

  1. 表示层或用户界面层

  2. 业务逻辑层或控制层

  3. 数据存储层

图 5. 三层网络计算

表示层可以是 HTML 表单或 Java applet(如图 5 所示)。从表示中提取控制逻辑允许您对应用程序的表示进行网络启用。

它还允许最终用户使用成本较低的硬件与应用程序交互,因为他们的设备现在仅负责呈现由控制逻辑提供给它的信息。此外,表示系统不需要知道数据最初来自何处或以何种格式存储在数据库中——它只需要中间层的接口。

控制逻辑可以执行访问管理,根据需要更改信息的视图,以使不同的用户能够查看同一数据的不同子集——可能是出于安全原因。例如,医院的医生可能想要查看患者的病史,而财务部门的人员应该只能查看账单信息。在图 5 中,Java 或 CORBA 扮演业务逻辑的角色。

通过将控制逻辑与数据存储分离,您可以获得分布式计算的好处。您的逻辑可以封装数据库访问,为您提供关键任务数据的可扩展性和容错能力。所有公司信息来源都可以通过控制逻辑集成,以实现所谓的“数据仓库”——允许通过单个接口访问所有信息(当然,取决于安全许可)。

可以封装遗留系统,从而保护您现有的投资。通过标准化业务逻辑和数据之间的接口,您可以更轻松地替换或升级数据库系统。桌面机器(负责表示)无需修改。替换数据库的任务完全与该操作有关——将数据从一个数据库移动到另一个数据库,而不会影响系统的其他组件。

控制逻辑还可以增强数据存储系统的功能,执行其他功能,例如搜索信息以查找不明显的趋势(称为“数据挖掘”的过程)。

将应用程序系统划分为多个不同的层,并标准化这些层之间的接口,确保当您对一个层进行修改时,此更改对您的整个体系结构的影响是局部的。

总结

在本文中,我们介绍了通用对象请求代理体系结构,这是一种开发人员在实现基于分布式对象技术的应用程序时使用的工具。我们还讨论了面向对象的方法相对于传统功能方法(例如使用 RPC)在网络编程方面的优势。最后,我们介绍了对 CORBA 技术的主要兴趣之一——使用多层方法在网络上部署业务应用程序。

下一篇文章将讨论可用于 Linux 的各种 ORB 以及如何开始使用 CORBA 进行编程。

资源

首字母缩略词和缩写

Linux Network Programming, Part 3
Ivan Griffin 是爱尔兰利默里克大学 ECE 系的研究生。他的兴趣包括操作系统、宽带网络和多媒体。他维护着一个 Linux WWW 资源页面,网址为 oak.ece.ul.ie/~griffini/linux.html,他的电子邮件地址是 ivan.griffin@ul.ie

Mark Donnelly 也是爱尔兰利默里克大学 ECE 系的研究生。Mark 对合气道、Linux、CORBA、分布式代理和 Alpha World 感兴趣。他的电子邮件地址是 mark.donnelly@ul.ie

John Nelson 博士 是爱尔兰利默里克大学计算机工程高级讲师。他的研究兴趣包括电信(移动/宽带)、VLSI 设计和软件工程。他的电子邮件地址是 john.nelson@ul.ie

加载 Disqus 评论