企业集成模式-第三章

发布时间 2023-11-04 13:09:37作者: LHX2018

三、消息传递系统

3.1 引言

1)消息传递的基本概念

  • 通道:是一个虚拟管道
  • 消息:能通过通道传送的一个原子数据包
  • 管道和过滤器:在最简单的情况下,消息传递系统会把消息直接从发送者的计算机传送给接收者的计算机。但是,在消息从最初的发送者那里发出,直到最后的接收者接收到以前,往往需要对消息完成某些动作。例如,假设接收者所期望的消息格式与发送者使用的消息格式不同,那么必须对消息进行验证和转换。管道和过滤器体系结构描述了如何使用通道将多个处理环节链接起来。
  • 路由
  • 转换:把消息从一种格式转换为另一种格式
  • 端点:大多数应用没有提供与消息传递系统交互的内置功能。与此不同,它们必须包含一层代码,这些代码不仅知道应用如何工作,还了解消息传递系统如何工作,从而能够在应用和消息传递系统之间架桥,使它们能协同工作。这种桥接代码就是一组协同的消息端点,支持应用发送和接收消息。

2)本书的组织

image

3.2 消息通道

消息传递系统不是一个大桶,任由应用向它倾倒和抓取信息。它是一组连接,按照预先确定的、可预知的路径传送信息,从而实现应用间的通信。
image
通道是消息传递系统中的逻辑地址

3.3 消息

要在两个不同的进程之间传递一些数据,则需要做更多的工作。因为它们都有自己的内存空间,因此必须把数据从一个内存空间复制到另一个内存空间。数据一般作为字节流传送,这是数据的最基本的形式。也就是说,第一个进程必须把数据编组 (marshal)为字节形式,然后把它从第一个进程复制到第二个进程。第二个进程还要把数据解组(unmarshal)成原来的形式,这样一来,第二个进程就获得了第一个进程的原始数据副本。所谓编组,就是远程过程调用如何把参数发送给远程进程,以及远程进程如何返回结果。

一个消息由两个基本部分组成。

  1. 消息首部:由消息传递系统使用的信息,用于描述所传送的信息、其信源和信宿(目标)等等
  2. 消息体:被传送的数据,一般被消息传递系统忽略,只是原封不动地传送

如果应用发送的信息在一个消息中容纳不下,可以把它划分为更小的单元,将各个部分作为一个消息序列 (Message Sequence) 发送。如果数据只是在一定的时间期限内有用可以指定这样一个消息到期时间 (Message Expiration)。

3.4 管道和过滤器

在许多企业集成案例中,一个事件会触发一系列的处理步骤,每个步骤都要完成特定的功能。例如,假设在我们的企业里新订单以消息的形式到达。第一个要求是消息必须加密,以防止窃听者获知客户的订单。第二个要求是消息中要包含认证信息,认证信息采用数字证书的形式,以确保订单是由可信的客户所下。而且,外部客户可能会发送重复的消息。
image
过滤器可以进行组合

1)流水线处理

当某个单元完成了一个消息的处理后,可以把消息发送给输出通道,并立即开始处理下一个消息。它不必等待后续组件读取和处理该消息。这使得多个消息在通过各个处理阶被传递给认证组件。同时,下一个段时,能得到并行处理。
image

2)并行处理

但是,整个系统的吞吐量要受到处理链中最慢过程的制约。可以为该过程部署多个并发的实例来提高吞吐量。在这种情况下,需要采用有竞争消费者(Competing Consumer)的点对点的通道,来确保通道中的每个消息只能被N个可用处理器中的某一个消费(处理)这样可以加快时间最紧张的处理步骤,进而提高整体的吞吐量。但是需要注意的是,采用这样的配置可能会引起消息处理顺序不正常。如果消息的顺序非常关键,则只能为每个组件运行一个实例,或者必须使用重排器(Resequencer)。
image

3.5 消息路由器

image
消息路由器与管道和过滤器的基本概念不同,因为它要连接多个输出通道(也就是说,它有多个输出端口)

固有特性:它不会修改消息的内容,而只关心消息的目标。

尽管消息路由器的目的是为了使组件解耦合,但是使用它却会带来相反的效果。为了把消息发送到正确的通道,消息路由器组件必须了解所有可能的目标通道。如果可能的目标通道列表经常改变,消息路由器就会成为维护的瓶颈。在这种情况下,让每个接收者自已己选择感兴趣的消息可能更合适。可以使用一个发布-订购通道和一个消息过滤器数组实现上述目的。我们把这两种选择方案分别称为预测型 (predictive) 路由和反应型 (reactive)路由。

和大多数好的工具一样,消息路由器也会被滥用。随意地使用消息路由器会把松耦合的优点变成缺点。对于松耦合系统,很难获得解决方案的“整体映像”一一即经过整个系统的消息流。这是消息传递解决方案遇到的共同问题,而使用路由器更会让这个问题加剧如果系统中任何组件都与其他组件松耦合,要想掌握消息流动的真正方向是不可能的。这就会增加测试、调试和维护的难度。有许多工具可以帮助缓解这个问题。可以使用消息历史在运行时检查消息,查看它们经过了哪些组件。或者,可以建立一个列表,其中包含系系统中各个组件订购或发布消息的所有通道。根据这些知识就可以绘制出经过组件的所有可能的消息流图。

不同的消息路由器

固定路由器

基于内容的路由器:根据消息的类型或指定消息字段的值

基于上下文的路由器:按照环境因素决定消息的目标

3.6 消息转换器

image

1)转换的层次

处理对象 转换需求(举例) 工具/技术
数据结构(应用层) 实体、联合、维度 把多对多关系压缩为聚集 结构化映射模式、自定义的代码
数据类型 字段名、数据类型、值域、约束、码值 把ZIP码从数字转换为字符串;把名和姓合并成一个字段;把美国的州名用两个字符的代码表示
数据表示 1. 数据格式(XML、键值对、定长数据字段、EAI开发商特定格式等)2. 字符集 3. 加密/压缩 XML解析器
传输 通信协议:TCP/IP套接字、HTTP、SOAP、JMS
  • 传输层位于这个“栈”的最下面,提供不同系统之间的数据传输服务。它负责跨不同网段完整、可靠地传输数据,并处理数据包丢失和其他网络错误。

  • 数据表示层也被称为语法层 (syntax layer)。这一层定义了所传送数据的表示。由于传输层只负责传输字符或字节流,因此转换是必要的。也就是说,复杂的数据结构必须转换为一个字符串。经常需要转换为以下格式,包括 XML、定长字段(如 EDI 记录)和专用格式。在很多情况下,数据还要压缩或加密,并附加校验位或数字证书。为了与采用不同数据表示的系统打交道,数据可能必须解密和解压,并得到解析,然后提供(显示) 新的数据格式,可能还要压缩和加密。

  • 数据类型层定义了应用的数据类型,它是应用(域)模型的基础。这一层要做出一些决定,如把日期字段表示为字符串还是本地日期结构,日期是否要带一个日期时间组件,以及日期基于哪个时区等等。

  • 数据结构层描述了位于应用领域模型之上的数据,因此也被称为应用层。这一层定义了应用要处理的逻辑实体,如客户、地址或账户。它还定义了这些实体之间的关系。

2)解耦合的层次(略)

3)链接的转换

image
消息转换器模式有许多不同的特例和变种。信封包装器 (Envelope Wrapper)把消息数据包装在一个信封中,使它能通过消息传递系统传输。内容扩充器 (Content Enricher)在消息中增加信息,而内容过滤器(Content Filter)则从消息中去除信息。声明标签(ClaimCheck) 把信息从消息中去除,但同时会把所去除的信息保存起来,以备以后获取。规范器(Normalizer)把多种不同的消息格式转换为统一的格式。最后,规范数据模型展示出如何平衡多个消息转换器,从而实现数据格式的解耦合。在这些模式的内部,可能会出现复杂的结构转换(如把多对多的关系映射为一对一的关系)。

3.7 消息端点

image
消息端点是一个特殊化的通道适配器组件,要为应用定制开发,并集成到应用中。