现在的位置: 首页 > 综合 > 正文

基于服务的企业集成模式轻松入门,第 1 部分: 基本概念的演变

2018年03月29日 ⁄ 综合 ⁄ 共 4604字 ⁄ 字号 评论关闭

引言

使一个企业中的所有应用程序以集成方式运行以便提供统一而一致的数据和功能是一项非常艰难的任务。这涉及到各种应用程序,如自主构建的应用程序 (C++、Java™ 或 Java 2 Platform, Enterprise Edition [J2EE])、打包的应用程序(如 SAP CRM 应用程序)以及遗留应用程序(大型机 IBM® CICS® 或 IBM Information Management System [IMS™])。而且,这些应用程序可能分布在不同的地理位置,并可能运行于各种平台上。这可能需要集成企业之外的应用程序。

随着企业的发展,企业集成中涉及的复杂性也随着时间的推移而增加,并涉及了许多集成模式。因此,目前存在着大量的集成模式。这些集成模式各种各样,有的是基于文件在应用程序之间进行简单的数据传输,有的是完全基于 SOA 的集成模式。

本系列的第 1 部分和第 2 部分介绍这些模式的演变,目的是为了帮助您理解基于 SOA 的集成模式中涉及的所有基本概念和功能。涉及的一些概念和功能包括:

  • 服务的使用者和提供者
  • 松散耦合
  • 代码重用和分层
  • 语言独立性
  • 平台独立性
  • 服务接口的定义、发布和发现(即注册表概念)
  • 企业服务总线 (ESB) 从点对点集成发展,涉及连接性、封送处理和中介的概念
  • 粗粒度

集成模式发展的这些描述还重点强调了许多以前技术和技术概念大大促进了基于 SOA 的集成模式的发展。

讨论旧模式的另一个原因是,即使在当今世界,仍然存在着旧模式和新模式的共存现象。例如,许多 ESB 实现都支持集成的文件传输机制。类似地,许多应用服务器(如 IBM WebSphere®)都具有对象请求代理 (ORB) 和异步消息传递功能。

需要关注的是,最近 IBM 提议的标准化服务集成成熟度模型 (SIMM) 已得到 The Open Group 董事会的认可。在本系列文章的第 1 和第 2 部分中对早期集成模式的描述可以大大帮助您确定和明确 SIMM 中应用程序域的成熟度级别。

松散耦合

在所有概念中,倾向使用 SOA 类型集成模式的主要驱动因素是松散耦合思想。促进使用松散耦合的原因是集成的应用程序的数量和类型越来越多。这要求集成模式对一个应用程序的更改使对其他应用程序造成的影响减到最小。需要松散耦合的另一业务原因是企业需要灵活地满足当今不断改变的业务需求。因此集成模式必须能够满足这一变化和具有足够的灵活性。在本文中您将了解到,尽管通向松散耦合和灵活性的道路不是笔直的,但通常情况下,在我们从旧模式移动到 SOA 时,应用程序和软件组件之间的耦合已变得较弱。

最大化代码重用

促进开发基于服务的体系结构的第二个重要因素是强调最大化代码的重用。代码重用可以得到更可靠和更有效的代码,这是因为对相同的代码进行了反复测试。要实现代码重用,通常需要使用分层(也称为组件化)。分层组件化 是指作为单独的软件组件提取不同的代码片段,以便多个应用程序在运行时可以使用相同的代码进行到远程应用程序的网络连接。分层还促进了松散耦合,因为可以更改每层的内部工作,而不影响其他层或应用程序。

现在我们通过最简单的集成开始讨论集成模式,该集成仅涉及应用程序之间的数据共享。这可以帮助您了解不同应用程序之间连接性的概念。

仅共享数据

大体上讲,在两个应用程序之间共享数据的方式共有两种:

文件

第一种方式(可能是最常见的方式)是通过文件共享数据。这是因为将数据存储在文件中是在系统中存储数据的通用方法。在此集成模式中,一个应用程序将数据写入文件,另一个应用程序从同一文件中读取数据。但是,使用这种方法在应用程序之间共享数据存在两个主要问题:

  • 数据不能实时共享,这是因为在将数据写入文件和从文件中读取数据之间常常存在着延迟(主要依赖于业务周期)。
  • 共享数据的两个应用程序之间存在着紧密耦合关系。因此,生成文件的应用程序中的更改(修改文件的格式或内容)必须伴随使用该文件的应用程序中的更改。

 

公共数据库

共享数据的第二个模式与第一种模式类似并使用一个公共数据库。在此模式中,一个应用程序将数据写入数据库,另一个应用程序从该数据库中读取数据。这种模式同样不能实时共享数据,这是因为在一个应用程序将数据写入数据库与另一个应用程序从中读取数据之间存在着延迟。这种数据写入和读取之间的延迟是由于执行读取的应用程序不知道执行写入的应用程序何时将数据写入数据库所造成的。而且应用程序之间还存在着紧密耦合关系,由于对数据库的更改有一个连锁反应,因此这使得共享数据库的设计变得非常困难。

连接性

为避免过时数据的问题,在共享数据的应用程序之间需要实时连接。我们将其称为连接性。在两个应用程序之间建立连接性的最根本的方法是通过套接字进行连接。套接字 可让一个应用程序在给定计算机的给定端口上侦听数据,同时另一个应用程序可以使用第一个应用程序的 IP 地址和端口地址写入同一套接字。执行侦听的应用程序可以在第二个应用程序写入数据时就读取数据。因此数据是实时共享的,消除了数据过时问题。

由于与通过套接字进行通信的应用程序相关的开销非常低,因此直接套接字编程可以实现高效的通信。有趣的是,大多数现代通信方法,如面向消息的中间件 (MOM) 和封装的消息也依赖于套接字编程。不过,套接字编程方法存在着许多缺点:

  • 套接字编程的主要问题是仅能直接共享数据,而不能共享功能。
  • 套接字编程的 API 级别相当低,因此很难使用。
  • 由于 API 的级别很低,因此套接字编程不适于处理复杂的数据类型。
  • 连接代码隐藏在应用程序中,因此无法被重用。
  • 同时,套接字编程还不独立于平台,因为两端的应用程序必须在不同平台(如大型机和 UNIX®)上明确说明字节排序的差异(小端字节序与大端字节序)。
  • 由于套接字连接是点对点连接,因此两个应用程序之间也存在着紧密耦合关系。

所以,我们需要一种解决方案,既能让应用程序共享数据 功能,又能避免低级别的网络编程。RPC 是可以让应用程序共享功能的首选方法,下面将介绍这种方法。

远程过程调用

介绍 RPC 是一个重要步骤,因为它引入了一些重要概念和功能,并指定了共享功能所需的基本步骤。您还记得,服务实质上就是应用程序之间和组件之间共享功能。因此,详细讨论此集成模式非常有意义。

RPC 也称为客户端/服务器模式,它在套接字编程的上一级别。该模式省去了网络编程这一需要。简言之,RPC 提供了面向功能的接口。开发人员定义一个函数,这与 C 语言中的函数语言非常类似,并生成代码,使该函数对调用方而言看上去就像一个常规函数。RPC 的功能非常强大,足以作为客户端/服务器应用程序的基础。

RPC 引入的第一个有价值的概念是称为服务器的服务提供者和称为客户端的服务使用者。在 RPC 中,服务器应用程序提供一个可以由使用者(客户端)应用程序通过常规方式调用的函数。基本顺序是服务器(应用程序)启动,等待客户端发出请求。当服务器从客户端收到请求后,服务器执行本地函数,并将该函数的返回值返回给客户端。图 1 显示了完整的流程。

图 1. 远程过程调用的完整流程
远程过程调用的完整流程

图 1 中引入的一个重要组件是客户端存根(stub)。对于客户端,客户端存根显示为其调用的实际过程。存根的目的是将参数打包到远程过程中,可能将这些参数放入标准模式中,然后构建一个或多个网络消息。将参数打包称为封送(marshaling)。此封送的一个重要方面是不同平台之间的字节排序差异自动使用名为外部数据表示 (external data representation,XDR) 的标准进行处理,从而使 RPC 独立于平台。

RPC 引入的第二个重要组件是远程过程调用运行时库(RPC runtime library)。客户端存根使用 RPC 运行时库提供的函数将系统调用转换为本地内核,并使用一个协议(如传输控制协议 (TCP))将打包的消息通过网络发送到服务器计算机。换句话说,RPC 运行时库封装连接所需的所有系统调用——即,通过网络发送打包的参数。因此,程序员不需要知道任何系统编程。

在服务器计算机端,当内核中的网络例程接收到网络消息后,它使用 RPC 运行时将该消息发送到服务器存根。服务器存根解封输入参数,并将请求的本地过程调用到服务器例程。在完成本地过程之后,服务器存根将返回值封送到一个或多个网络消息中,并将打包的返回值通过使用 RPC 运行时发送到服务器存根。服务器内核使用网络协议(如 TCP)将消息发送到客户端计算机。客户端存根通过使用 RPC 运行时例程从内核中读取网络消息。在转换返回值之后,客户端存根最终返回到客户端函数。此步骤是返回到客户端的常规步骤。

RPC 还引入了一个通过使用规范文件定义客户端和服务器之间接口的根本方法。可以将 RPC 规范文件视为当今世界服务接口开发中的第一步。清单 1 中提供了此类配置文件的一个示例 (square.x)。此文件通过 rpcgen 之类的工具为服务器和客户端生成框架代码。注意,该规范是特定于语言的(如 C 语言),因此要求服务器和客户端使用同一种语言编写。

清单 1. RPC 规范文件的一个示例,该文件为计算一个数的平方定义了一个远程过程

                
struct square_in {		/* input (argument) */
	long 	arg1;
};
struct square_out {          	/* output (result) */
	long 	result;
 };
 program SQUARE_PROG {
   	version SQUARE_VERS {
		square_out SQUAREPROC (square_in) = 12;   	 /*procedure number*/
	} = 23;							/* version number */
 } = 0x31231234;						 /* program number */

为概括说明什么是 RPC,需要注意的重要一点是,RPC 通过让应用程序共享功能允许第一个实例进行实际分布式计算。在此过程中,引入了一些新概念,其中包括:

  • 服务提供者(服务器)和服务使用者(客户端)。
  • 平台独立性。
  • 接口定义的概念。
  • 封送输入和输出参数。
  • 在库中封装网络通信所需的系统调用。

不过,RPC 存在着许多缺点,其中包括:

  • 主要缺点是几乎没有代码重用空间。这是因为用于封送和解封的代码以及用于网络通信的代码隐藏在客户端和服务器应用程序中。
  • RPC 不是独立于语言的,并且客户端和服务器必须采用相同的编程语言
  • 并且应用程序之间也存在非常紧密的耦合。这是因为调用是同步进行的,客户端应用程序必须等待服务器完成该过程才能执行进一步处理。而且,虽然可以通过使用多线程克服此问题;但是,这导致了另一级别的编程复杂性,该方法存在着垃圾收集方面的固有风险。
  • 客户端和服务器集成是点对点集成,因此,当需要集成许多应用程序时,这种方法不合适。
  • 在涉及大量的远程调用时,也不适合使用 RPC。这是因为调用是同步进行的,此特征使客户端只能在服务器完成其工作之后才能进行处理。

结束语

本文描述了两个最早的集成模式。第一个是套接字编程,该模式适用于实时共享数据,第二个是远程过程调用,该模式适用于共享功能。还学习了连接性、服务提供者和服务使用者以及平台独立性概念。

为了改进远程过程调用,共采用了两种方法。第一种方法是使用分布式对象(也称为对象请求代理),第二种方法是使用异步消息传递。分布式对象方法侧重于代码重用和语言独立性,而异步消息传递则解决了应用程序之间紧密耦合的问题。在本系列的第 2 部分中,您将首先学习分布式对象方法,它与远程过程调用方法的关系更密切。还需要指出的重要一点是,如今大多数应用服务器都基于 ORB 技术。

抱歉!评论已关闭.