一.消息概述
BizTalk Server 基于消息发布/订阅的基本机制,在BizTalk Server内部分为发布服务器和订阅服务器,所谓发布服务器就是产生消息并发布到MessageBox中,所谓订阅服务器就是可以消费消息的服务器,根据订阅的消息的条件,只对自己需要的信息进行处理。
一般的情况是从外部收到的信息经过接收端口后都会被处理转换包装成biztalk的消息,消息中包含了相关属性(消息上下文),比如接收的端口、接收的适配器信息,还有预设的从消息内部提取出来的可以用来路由消息的特征值(从schema升级的属性)。把然后存放到消息数据库MessageBox中。
消息代理根据订阅表查找订阅了此消息的服务,并将订阅了此消息的所有订阅分别存到的相应的服务器实例对应的消息队列表中,系统不断的轮询此队列,发现有未处理的消息,就会把消息发送到订阅此消息的服务,同时把此条订阅消息从消息队列表去除。
订阅消息的服务(这个服务可能是业务流程,也可能是输出端口等等)收到消息后对消息就行处理,处理完后,如果服务是输出端口,此消息就经过适配器发送到系统外部。如果服务是业务流程,可能会产生新的消息,这种情况的处理同从接收端口进来的消息做类似的处理,发送消息到MessageBox,并查找订阅此消息的服务,把消息发送到订阅消息队列中继续流转。
1. 发布和订阅服务器
发布服务器指的是可以送出消息发布到MessageBox的服务,包括:
接收端口 ―― 从外部接收信息,处理后发布到MessageBox
业务流程 ―― 业务流程启动后可能生成消息发送到发送端口或启动别的业务流程,生成的消息也是发布到MessageBox
要求/响应(Solicit-Response)发送端口 ―― 即双向的要求/响应发送端口。
订阅服务器是可以订阅并消费消息的服务,可以作为订阅服务器的服务类型目前有四类:
XLANG/s – 业务流程(orchestration)
Messaging InProcess – 表示发送端口,Solicit- Response发送端口
MSMQT – MS消息队列
Messaging Isolated – 表示请求/响应(Request-Response)接收端口,目前基本上就是指HTTP和SOAP的Request-Response双向接收端口。
Biztalk中的发布和订阅都是相对MeassagBox而言的,导致消息进入到MeassagBox的就叫发布,根据条件从MeassagBox中取得消息的叫订阅。
2. 消息构成
BizTalk Server 2006 本质上是一个消息处理引擎。每条消息都可视为多部分消息,此消息可以由零个或多个部分组成。具有一个或多个部分的消息都具有一个标识为正文部分的部分(只能有个一部分标识为正文)。每个部分均由可表示 XML 文档、平面文件、序列化的 .NET 类或其他二进制数据流的二进制数据块组成。消息的正文部分的类型决定了整个消息的类型,这个消息类型可用为路由消息的条件。
2.1. 上下文
每条消息都附带有一个属性集,称为消息上下文,这些属性的值是从消息本身提取或不来自消息本身但与消息本身相关的值。属性分为两种类型,升级属性和写入属性。这两种属性的区别是升级的属性可以用来作为路由消息的条件,写入的属性不能。
2.1.1. 升级属性
要把一个消息架构中的某个元素升级到上下文属性,首先要有一个属性架构来对应各个被升级的属性。这个属性架构是简化的架构,只能包含简单数据类型的元素,每个元素对应一个属性,并分配给这个属性一个GUID,用来标识这个属性。看一下升级属性架构中的一个属性:
<xs:element name=”Property1” type=”xs:string”>
<xs:annotation>
<xs:appinfo>
<b:fieldInfo propertyGuid=”4bfe2aee-9c25-436f-979d-862ed812a523” />
</xs:appinfo>
</xs:annotation>
</xs:element>
属性名是Property1,属性GUID是4bfe2aee-9c25-436f-979d-862ed812a523。升级消息架构中的属性,先要在消息架构中指定升级架构,然后把消息架构中的某个元素对应到升级架构中的某个同数据类型的属性。消息架构中的元素被升级后,消息架构会保存此升级属性在架构中的位置信息的xpath,以便可以通过xpath提取元素的值。
如果接收管道中使用了xml拆装器,则消息经过接收端口的管道时,xml拆装器会自动把入站的消息跟已部署的消息架构匹配,匹配到合适的消息架构后,管道根据消息架构中升级属性的xpath提取相应的值保存到上下文属性,然后消息代理把这些属性的GUID和值保存到BizTalkMsgBoxDb数据库MessageProps 表中,就可以根据订阅的条件对照这些属性来路由消息。
比如某个服务订阅了消息类型为订单、收货单位为xxxx的消息,这里消息类型和收货单位都是升级到上下文属性的属性,消息代理发现这个条件跟收到的消息一致就会把消息发送到这个订阅的服务。
升级的属性除了从消息本身升级来的外,还有不是消息本身的信息但跟此消息相关的系统属性,比如接到此消息的端口适配器类型,接收此消息的端口id等等,这些系统属性也都具有自己的guid,会同其他的升级属性一同写入到MessageProps 表中作为路由消息的依据。
关于详细的消息订阅和消息发布路由的机制下面有专门章节论述。
2.1.2. 写入属性
写入属性就是把消息架构中的某个元素设置为可分辨字段(Distinguished),消息架构会保存此写入属性在架构中位置信息的xpath,以便可以通过xpath提取元素的值。
写入的属性不必有属性架构的支持,也就没有相应的GUID,属性会被提取出来保存到上下文属性中,但是写入的属性不能用来作为路由消息的条件。
写入属性一般是为了在业务流程中方便的访问消息中的某个元素,可以直接从消息上下文属性获得此属性值,省去开发人员手工解析提取这个元素的值麻烦。
2.2. 多部分
biztalk中的消息又叫做多部分消息,意为一个消息可以包含多个部分,每个部分都可能为XML 文档、平面文件、序列化的 .NET 类或其他二进制数据流的二进制数据块。一个消息可以是简单的只包含一个部分的消息,也可以有多个部分,但是其中必须并且只能有一个部分为正文本分,正文部分的类型就是整个消息的消息类型。
3. 消息流程
先看一下消息在biztalk中的流转过程的图,下面详细描述一个从接收端口进入到biztalk后一直到消息发送出biztalk的整个过程。
3.1. 接收端口
一个接收端口可以包含多个接收位置,每个接收位置就是一个对外接收信息的实际物理接口。接收位置接收到的信息经过处理,如果设计有映射,经过消息映射转化后再由消息代理根据消息订阅情况分发到各个订阅消息的服务。
接收位置:
接收位置主要由接收适配器和接收管道组成,这两个组件再终结点管理器的管理下协调工作。
接收适配器:
Biztalk作为EAI和B2B的平台软件,需要跟各种系统通讯联系,所以信息接口应该覆盖面尽可能的广,能够接收各种协议的各种类型的信息,biztalk使用适配器来解决这个问题,通过适配器来把多种多样的信息接收进来并转换成biztalk内部使用的xml的消息。
Biztalk本身包含了许多一般常用的适配器SOAP、http、ftp、Smtp、平面文件、msmq、sql等等,基本能满足大多数需求。如果biztalk本身带的适配器不能满足需求,还可以自己开发需要的适配器,另外有很多第三方的公司也提供各种自己开发的适配器给需要者使用。
接收适配器读取数据流创建消息(Microsoft.BizTalk.Message.Interop.IbaseMessage 接口的实现)、向该消息添加部分(Microsoft.BizTalk.Message.Interop.IbasePart 接口的实现)、然后将数据流作为该部分内容进行提供。
接收消息后,适配器将接收位置、适配器类型以及其他内容(与适配器相关)升级到消息的上下文属性中,以便根据接收位置或适配器类型订阅消息的服务能接收到订阅的消息。
接收管道:
从适配器出来的消息在终结点管理器的控制下送到接收管道中进行处理。
接收管道如上图包含四个阶段的处理,这里我们重点关心的是拆装部分,biztalk提供了两个拆装器:xml拆装器和平面文件拆装器。
Xml拆装器可以指定消息的架构,xml拆装器就会按照这个消息的架构对消息就行处理,并可以校验消息是否符合架构。同时如果消息架构中有升级属性,这一步会根据升级属性的xpath把属性值从消息中提取出来放到消息的上下文属性中。指定了消息架构的xml拆装器还会把消息的类型升级到消息的上下文属性中,消息的类型为命名空间(后接 # 符号)和根节点的名称组成。比如:http://tempuri.org/samples/MessageType#Message
平面文件拆装器需要指定架构,并且架构是做过平面文件扩展的,就是架构中包含如果分解平面文件数据到xml的信息,平面文件拆装器根据这些信息解析平面文件,并生成xml。
Biztalk的默认接收管道PassThruTransmit是个直通的管道,它不处理xml文档,所以如果要接收xml消息并升级属性此管道不适合。
Biztalk的默认接收管道XMLReceive,这个管道专门用来拆装xml消息,管道中的xml拆装器根据架构的命名空间和根节点名称在已经部署的所有架构逐个进行匹配,一旦匹配成功,就使用这个架构,然后根据schema中升级属性的xpath提取属性值放入上下文。如果一个都没匹配成功,则根据是否路由不可识别消息的设置确定是否继续路由,还是生成错误信息。
消息代理:
接收管道出来的消息又回到终结点管理器,如果有映射器就把消息送到映射器就行消息的架构转换,如果没有把消息直接送到消息代理,由消息代理把消息发布到MessageBox中,并处理消息的路由。
消息的发布和路由在下面章节详述。
3.2. MessageBox
Microsoft BizTalk Server 中发布/订阅引擎的核心是 MessageBox 数据库。接收到的消息存放在MessageBox中,各个服务消息订阅也是存放在MessageBox中,发送到订阅服务的消息队列也是在MessageBox中。MessageBox是biztalk的信息核心。
3.3. 业务流程
业务流程可以参与消息的处理过程,但业务流程不是处理消息过程的必须过程,一个消息流程完全可以直接从接收端口到MessageBox,然后直接路由到一个输出端口,不需要业务流程的参与。
业务流程中也有端口概念,是业务流程内部跟外部进行消息交换的接口,业务流程的端口称作逻辑端口,用户从biztalk外部接收数据、发送数据的端口称作物理端口,是不同的概念。
业务流程可以作为发布服务器也可以作为订阅服务器,作为订阅服务器时可以订阅从物理接收端口进入biztalk的消息,作为发布服务器,业务流程从逻辑输出端口输出的消息也可以被别的订阅服务器订阅。
业务流程内部的各种功能不在本文的讨论范围,可以自行参考biztalk的随即文档的业务流程相关的部分。
3.4. 发送端口
在消息准备从 BizTalk Server 发送时,它将在发送端口中经历一个互补的过程。映射将在发送管道执行前应用于消息,从而,消息在由管道处理并通过适配器发送前转换为特定于客户或应用程序的格式。在发送管道中,属性将从上下文降级到消息中,而非升级到消息上下文中。