企业集成有很多种模式,随着技术的发展,实时的、面向消息的企业集成越来越成为主流,面向消息的企业集成的稳定性和兼容性要求其基础件,也就是
message
系统必须提供足够强壮和可扩展的设计,下面几种是作为面向消息的企业集成的基础件所必须提供的几个关键性组件。
消息集成使得
message
系统负责转换两个应用之间的数据格式,从而使得应用可以专注于他们需要共享什么数据而不是如何共享它们。
以下这些组件,在著名的ESB系统Mule中都可以见到,有兴趣的同学可以去看看Mule的源代码,虽然Mule对ESB的实现有很多不成熟的地方,以至于让我不敢在生产系统中使用(唉...可恨的Mule),但是毕竟是一个大而全的系统,值得借鉴一下。
Channels
— Messaging
应用通过一个
Message Channel
传送数据,一个
sender
到
receiver
的虚拟管道。一个新安装的消息系统默认不包含任何
channel
;你必须知道你的应用需要怎样通讯,然后才能建立
channel
来完成它。
Messages
— Message
是在
channel
上传输的不可分割的包。因此,为了传输数据,应用必须将数据打包成一个或多个
packets
,将每个
packet
包装成一个
message
,然后将其传输到一个
channel
。同样的,一个
receiver
应用在接受到
message
后必须从
message
中提取出数据才能使用。
Message
系统应该能重复的传输
message
,直到它成功为止。
Pipes and Filters
—
最简单的情况下,
message
系统将一个消息直接从
sender
计算机传送到
receiver
计算机。然而,通常在消息从
sender
中发出后,
receiver
接受到之前,有一些动作需要对
message
执行。举例来说,
message
也许需要验证或者转换。
Pipes and Filters
架构使用
channel
将多个处理步骤连接起来。
Routing
—
在一个大型的、拥有许多不同的应用和
channel
连接的企业应用中,一个
message
可能需要穿过多个
channel
才能到达最终目的地。
Message
的路由如此复杂以至于最初的发送者无法知道那些
channel
能将
message
传送给最终的
receiver
。因此,最初的发送者将
message
发送给一个
Message Router
,一个以
Pipes and Filters
架构中的
filter
形式存在的应用组件。
Router
将决定如何将
message
发送到最终
receiver
或者至少是下一个
Router
。
Transformation
—
不同的应用的数据格式可能不同。为了调节
sender
和
receiver
之间的数据格式不同的问题,
message
必须经过一个中介的
filter
,一个
Message Translator
,它将
message
从一个格式转换成另外一个格式,或转换成一个公共的格式。
Endpoints
—
大多数的应用程序没有内建的能力来同一个
message
系统交互。因此他们必须包含一个中间层,它知道应用系统如何工作,也知道
message
系统如何工作,并桥接两个系统。这个系统是一组并列的
Message Endpoints
,它能够使得应用发送和接受
message
。
System manager
-
作为一个大型的消息集成系统,其面向消息的、异步、低耦合的本质使得系统更加难以调试,运行期的状态也难以跟踪,所以,我们必须有强有力的手段进行系统的运行期管理和监控,同时最好能够在运行进行动态更新,以保障系统的强壮性。
企业应用集成是一个巨大而复杂的系统,作为其基础件
ESB
系统,必须能够提供对其完全的支撑以及足够强壮的系统,这正是
ESB
系统建设的难度所在。
在前面一个专题中,我们列出了一个
ESB
系统所需要关心的所有方面的关键组件,这里介绍其中的
Message Channels
所关注的问题及相关的模式。
Message Channel
主题之下包含以下模式,分别用于解决
channel
中不同方面的问题:
l
Point-to-Point Channel
l
Publish-Subscribe Channel
l
Datatype Channel
l
Invalid Message Channel
l
Dead Letter Channel
l
Guaranteed Delivery
l
Channel Adapter
l
Messaging Bridge
l
Message Bus
当两个应用需要交换数据,它们通过连接两端的
channel
来发送数据。发送的应用可能不知道哪个应用将接受数据。然而,通过选择特定的
channel
来发送,发送者知道接受者将是守候在
channel
另一端等待数据的应用之一。通过这种方式,生产数据的应用有了一个同数据消费者通讯的途径。
Message Channels
面对的各个主要问题:
如果一个应用要传输或接受数据,它一定会用到一个
channel
。问题是你的应用要知道要使用什么样的
channel
,以及用它来做什么。
固定的
channel
集合
-
Channel
中讨论的一个主题是,一个应用可用的
Message Channel
集合一般是固定的。设计一个应用时,一个开发者必须知道将某种类型的数据放到哪里可以同其他应用共享该数据,以及从什么地方可以找到其他应用的特定数据。这些通讯路径不会在运行期动态的创建和发现;它们需要在设计期间就确定下来,以便应用知道它的数据从哪里来以及数据将去哪里。(
虽然大多数
channel
必须被静态定义使正确的,但是也有例外,有些情况下动态
channel
是很好用的。一个例外就是
Request-Reply
模式中的
reply channel
。请求者可以创建或者获得一个应答者不知道的新的
channel
,并在请求消息中指定该
channel
为
Return Address
,应答者就可以使用它。另外一个例外是支持集成
channels
的消息系统实现。一个接受者可以订阅一个集成体系的根
channel
,然后发送者可以发布消息到一个子
channel
,而接受者不需要知道子
channel
,仍然会收到消息。这些都是不常见的情况,
channel
通常仍然是在部署之前被定义,并且应用被设计连接到一个已知的
channel
集合
)。
决定
channel
的集合
-
一个相关的主题是,谁决定那些
Message Channel
是可用的
-
message
系统还是应用程序?换句话说,是由消息系统确定一些
channel
,然后要求应用程序使用它们?还是应用决定它们需要什么
channel
,然后要求消息系统提供它们?这个问题没有一个简单的答案,设计必须的
channel
集合是迭代的。首先,应用要决定消息系统提供哪些
channel
。然后应用将围绕这些
channel
设计它们的通讯,但是如果这样是不可行的,它们将需要添加额外的
channel
。当一些应用已经使用了一个确定的
channel
集合,当加入新的应用,它们将使用已存在的
channel
。当为应用添加新的功能,它们需要新的
channel
。
单向
channel
-
另外一个经常引起混淆的是一个
Message channel
是单向的还是双向的。技术上来说,两者都不是,一个
channel
更像是一个桶,一个应用放入数据,另外一个应用从中取出数据。但是由于数据是放在消息中从一个应用传到另一个,这使得
channel
具有方向性,使它变成单向的。如果一个
channel
是双向的,应用将从中发送和接受数据,虽然技术上是可行的,但是会有小小的问题,应用将有可能持续的取出自己放进去的希望发送给其他应用的消息。所以,为了实践性的目的,
channel
是单向的。作为结论,两个应用如果有双向通讯,它们需要两个
channel
,每个方向一个
。
如何使用
Message channels
:
现在我们来讨论以下如何使用
channel
。
一对一或者一对多
-
当你的应用共享一些数据,你希望只将它共享给一个应用还是对它感兴趣的所有应用?要传送数据到一个单独的应用,使用
Point-to-Point Channel
。这并不意味着发送到这个
channel
的每个数据都发送给同样的接受者,因为一个
channel
可能有多个接受者。它意味着,实际上,保证每个数据都被同一个应用接收。如果你想让所有接收应用都能接收数据,使用
Publish-Subscribe Channel
。当你通过这种方式发送数据,
channel
将高效的复制数据到每一个接收者。
什么类型的数据
-
任何内存中的数据都有一个类型。另一方面,所有数据都是一些
bytes
集合。消息系统工作同这类似,消息内容必须符合某些类型以便接受者了解数据的结构。
Datatype Channel
认为在一个
channel
中的数据必须拥有同样的类型。这也是为什么消息系统需要很多
channel
的主要原因
(每个
channel
一种格式)。如果数据可以是任意的格式,那么消息系统在两个应用之间只需要两条
channel
。
无效的和过期的消息
-
消息系统可以确定消息被正确的传输,但是它不能保证接受者知道如何处理它。接收者对数据格式和意义存在期望。当它接收到一个不符合期望的消息,它什么也不能做。它们能作的,就是将这个陌生的消息放入到一个特别设计的
Invalid Message Channel
并希望某些监控这个
channel
的工具能够取出这个消息,并指出该如何处置它们。许多消息系统有一个类似的内建特征,一个
Dead Letter Channel
,用来存放成功送出但却无法成功投递的消息。另外,一个系统管理工具应该监视
Dead Letter Channel
并且决定如何处置这些无法投递的消息。
故障检测
-
如果一个消息系统发生故障或停机维护,它的消息会怎样?当它重启并重新运行,它的消息能否还在它的
channel
中?默认的:不会;
channel
将消息存储在内存中。然而,
Guaranteed Delivery
将
channel
持久化以便将它们的消息存储到硬盘上。这会影响效率,但会使消息更加可靠,即使消息系统是不可靠的。
非消息客户端
-
如果一个应用不能连接到一个消息系统但是仍然想要参与消息怎么办?通常它只能自认倒霉了,但是如果消息系统可以通过某种方式连接到应用系统
-
通过它的用户界面,它的
service API
,它的数据库,或者一个
TCP/IP
或
HTTP
这样的网络连接
-
那么消息系统可以使用一个
Channel Adapter
。这允许你连接到一个或多个连接到应用的
channel
而不必改变应用或者可能也不需要一个同应用运行在同一个机器上的消息客户端。有时‘非消息客户端’真的是一个消息客户端,但是只有连接的是其他消息系统的时候。
通讯中枢
-
随着越来越多的企业应用系统连接到消息系统以便通过消息暴露他们的功能,消息系统变成了企业中一站式功能的集散地。一个应用只需简单的知道用哪个
channel
来请求功能,以及从哪个监听结果。消息系统本质上变成一个消息总线,一个提供所有企业应用甚至变化中的应用和功能的中枢。你可以更快速的集成。
如你所见,使用消息构建应用不仅仅是将他们连接到消息系统并发送消息。消息必须使用
Message Channel
来发送。
Channel
必须被设计为某个目的服务,比如基于被共享的数据类型,共享数据的应用类型,和接收数据的应用。
3
在前面的
关键组件
中我们提到了
Messages
。当两个应用想要交换数据,他们将数据包装在一个
message
中。但是一个
Message Channel
不能传输原始数据,它只能传输包含在一个
message
中的数据(即传输特定格式的数据)。
Message
在消息系统中处于信息载体的位置,而在
ESB
中,还消息识别、序列以及生存周期等职责。
Message
的结构涉及以下几个模式:
l
Command Message
l
Document Message
l
Event Message
l
Request-Reply
l
Return Address
l
Correlation Identifier
l
Message Sequence
l
Message Expiration
l
Format Indicator
创建和发送一个
Message
产生以下几个问题:
消息意图
-
Message
最终是为了运送一些数据,但是发送者可能有其他目的,比如它希望接受者使用消息做些事情。它可以发送一个
Command Message
,指定它希望调用的接受者上的函数或方法。发送者告诉接受者运行那些代码。发送者可以发送一个
Document Message
来传送它的数据结构到接受者。发送者发送数据到接受者,但是不指定接受者应该做什么。
或者它可以发送一个
Event Message
,通知接受者发送者那里有一个改变。发送者不应告诉接受者应该怎样适应这个改变,而只应提供通知。
返回一个应答
-
当一个应用发送一个消息,它通常期望得到一个回应来确定消息被处理并提供一个结果。这是一个
Request-Reply
场景。
Request
通常是一个
Command Message
,而应答是一个包含返回值或异常的
Document Message
。请求者应该在请求中指定一个
Return Address
来告诉应答者使用哪个通道来传回应答。请求者可能在一个处理过程中发送多个请求,所以应答应该包含一个
Correlation Identifier
来指出这个应答对应哪个请求。
有两个
Request-Reply
场景需要注意;它们都包含了一个
Command Message
请求和一个对应的
Document Message
应答。在第一个场景中,
Message RPC
,请求不但要调用应答者的函数,而且期望一个返回值。这是
RPC
。另一个场景中,
Message Query
,请求者执行一个查询;应答者执行查询并在应答中返回结果。这是远程查询。
大量的数据
-
有时应用想要传送大量的数据结构,放入一个单独的
message
里面不是很合适。在这种情况下,将他们分解成可管理的消息块并将他们作为
Message Sequence
发送。这些消息必须按顺序发送,以便接受者能够充足原始数据结构。
慢速消息
-
消息系统的一个问题是发送者通常不知道接受者要多久才能接受到消息。然而,消息的内容可能是时间敏感的,所以如果消息在某一时间内没有被接受,它将被忽略并取消。在这种情况下,
sender
应该使用
Message Expiration
来指定一个到期时间。如果消息系统在规定时间内无法传输一个消息,应该将它取消并删除到
Dead Letter Channel
中。同样的一个
receiver
接受到一个超出该时间点的消息,也要取消该消息。
总之,只选择使用消息是不够的。使一个消息工作的其他决定性因素来自于消息所要完成的任务。
#
【
ESB
专题】之三
-
Message Construction
及其相关模式
[TrackBack] 回复
# re:
【
ESB
专题】之三
-
Message Construction
及其相关模式
回复
好文
,
我也正想研究
EAI
平台
,
其中
ESB
则是
EAI
平台的核心
,
期待你的后文
,
另
:
能否多讲一些有关
IBM MQ
的消息中间件
,
在大型企业应用中
,
往往都采用的是
MQ
渠道
,
毕境简单的基于
SOAP
连接的
WEB SERVICE
拥有先天缺陷
---
无法共享连接
.
# re:
【
ESB
专题】之三
-
Message Construction
及其相关模式
回复
呵呵,没用过
MQ
,所以没办法写关于
MQ
的内容了
我想
SOAP
的好处是基于
XML
的标准提供了互通的平台,并且它在消息转换、元数据交换以及安全方面都提供了标准的做法,我认为
SOAP
是一个很有前途的集成手段
SOAP
的缺陷是由
Http
协议的基于请求的、无状态的特性决定的,这也没办法
但是可以通过一些设计模式来适当的改变这种状态,比如使用
Cache
或硬性的保持一个通知连接等机制
# re:
【
ESB
专题】之三
-
Message Construction
及其相关模式
回复
是的
,
不论怎么样
,
在
SOA
应用架构下
,
基于
SOAP
协议的交互的确是相当重要的
,
因此才出现了面向消息的
SOA
实现
,
这就会在
ESB
里的消息通迅模式里解决
.
而
IBM
的
MQ
则是比较好的方案了
# re:
【
ESB
专题】之三
-
Message Construction
及其相关模式
回复