深入biztalk消息以及消息订阅发布路由机制(二)-消息订阅

一. 消息订阅

订阅消息的主体叫订阅服务器,订阅服务器是可以订阅并消费消息的服务,可以作为订阅服务器的服务类型目前有四类,在BizTalkMgmtDb管理数据库中的adm_ServiceClassName字段列出了所有可以作为订阅服务器的服务类型,包括:

XLANG/s – 业务流程(orchestration

Messaging InProcess – 表示一般的发送端口、Solicit- Response发送端口

MSMQT – MS消息队列

Messaging Isolated –基本上就是指HTTP和SOAP这类需要外部IIS这类进程接收消息的Request-Response双向接收端口

 

每种服务都有自己的id,为16字节GUID的形式(biztalk中对象的标识id都采用GUID的形式,biztalk数据表中大量的使用到这种16字节的统一标识数据,sql server中的uniqueidentifier 数据类型,就是用来存放GUID类型的数据)

 

1.  消息订阅主体

消息订阅最后体现在BizTalkMsgBoxDb数据库的反应订阅主体的Subscription表(表示是哪个服务产生的这个订阅)和反应订阅条件的一组谓词表中(表示这个订阅的具体条件,用来判断哪些消息是符合这个订阅的)。

先来看一下Subscription表的主要字段含义,这个表指示了订阅消息的具体是哪一个服务:

nvcName ―― 此订阅的名称

uidSubID ―― Guid类型,此订阅的uid

nvcApplicationName ―― 订阅服务器所属主机实例名,路由消息时不同的主机实例将调用不同的存储过程处理。

uidClassID ―― 产生订阅的服务类型,adm_ServiceClass 服务表UniqueId字段的外键

uidServiceID ―― 产生此订阅的具体服务,根据uidClassID服务类型的不同,对应到不同类别的服务.如果uidClassID指示的是XLANG/s,则对应的是业务流程,此字段对应到bts_Orchestration表中的uidGUID字段。为Messaging In-Proc时,表示由发送端口订阅消息,对应到bts_SendPort表中的uidGUID MSMQt时有点混乱,但大多数情况下也在bts_SendPort table表中体现。实例订阅时,服务实例是请求/响应端口时的这个字段并不是接收端口的guid也不是接收位置的guid,不清楚这个guid跟什么对应。哪位知道的朋友能不能告知一下。

uidInstanceID ―― 实例订阅时的订阅消息的服务实例的guid。激活订阅时此字节为空。

Biztalk中存在两类订阅:激活订阅和实例订阅。激活订阅收到执行订阅的消息后,该消息创建新的订阅服务器实例来处理这个消息,一般的订阅都属于这类订阅。实例订阅将指示执行订阅的消息应路由到已在运行的订阅服务器实例。有一种服务会产生实例订阅的情况即“Messaging Isolated ”,这类服务的典型就是请求/响应接收端口,这类服务其实可以产生两个订阅。先是请求/响应接收端口的接收部分,这部分相当于消息分布服务器,可以由其他订阅服务器来订阅这个消息,比如一般是业务流程的一个接收形状绑定这个端口,实际上就是订阅了这个端口接收到的消息。这个接收端口服务实例建立后,把收到的消息发送到MessageBox。然后请求/响应接收端口的响应部分,这部分相当于订阅服务器,如果这部分绑定到业务流程的一个发送形状,这个接收端口服务实例会生成一个实例订阅,这个字段就用来存放这个接收端口服务实例的guid,表示还是由这个服务实例来处理返回的消息。这样,就完成了一个从接收到响应的一个往返过程。实例订阅是由服务实例生成的订阅,所以在产生实例订阅收到消息被放入到消息队列后,会在订阅表中把这个实例订阅删除。

还有一种情况会形成实例订阅,orchestration中使用相关集时,一个orchestration实例的一个端口发送消息出去,返回的消息仍然由这个orchestration实例的一个接收形状接收。这里也有一个orchestration实例的订阅发出去的消息的实例订阅。

uidPortID ―― 订阅服务类型为XLANG/s,此字段表示业务流程中接收消息的端口形状,对应bts_orchestration_port表中的uidGUID字段。对于 MessagingMSMQt,这个字段指示使用发送端口的主通道还是辅助通道。先根据uidServiceIDbts_SendPort表中找到相应的端口,然后用bts_SendPort表的nID bts_sendport_transport表的nSendPortID 关联。uidPortIDbts_sendport_transport表的uidGUID 关联,就能确定使用哪个发送端口的通道。

fEnabled ―― 此订阅的状态,0 ―― 禁用;1 ―― 活动;2 ―― 停用

uidPredicateGroupID ―― 订阅谓词组id

 

2.  消息订阅条件(谓词)

一个订阅的主体存在Subscription表中,相应的订阅条件则分别存在一组谓词表中,不同的类型的条件放在不同的表中,比如等于的条件放在EqualsPredicates中,小于的条件放在LessThenPredicates中,一共有以下这么多的谓词表:

l         BitwiseANDPredicates

l         EqualsPredicates

l         EqualsPredicates2ndPass

l         ExistsPredicates

l         FirstPassPredicates

l         GreaterThanOrEqualsPredicates

l         GreaterThanPredicates

l         LessThenOrEqualsPredicates

l         LessThenPredicates

l         NotEqualsPredicates

这些表的基本结构都是一样的,都是按照什么属性(属性的GUID)+谓词(等于、大于、小于。。。)+属性的值的形式出现。看一下这些表的数据结构:

uidPropID ―― 属性的guid。所有属性都有自己的guid,包括类似接收端口、接收适配器类型等系统属性,或者从schema升级的属性。

vtValue ―― 属性的值

uidPredicateGroupID ―― 一组谓词的id,一个订阅可以有多个条件谓词,这个字段表示同一组的条件,条件也可分为或条件和与条件,条件的组合通过PredicateGroup表在Subscription表和各个谓词表之间进行组合。

看一下PredicateGroup表的结构:

uidPredicateORGroupID -- 订阅谓词,对应到SubscriptionuidPredicateGroupID字段表示是与这个订阅相关的条件。此字段相同的记录表示相应的订阅有多组条件用或运算组成。

uidPredicateANDGroupID -- 订阅谓词与运算一组的谓词id,每个或运算条件都能由多条与运算的条件组成,最终由这个字段跟各个谓词表去关联。

nNumFirstPassPredicates -- 这个或条件组中包含几个与运算条件。

深入biztalk消息以及消息订阅发布路由机制(二)-消息订阅_第1张图片
这个图中显示了一个发送端口设置筛选条件(就是设置订阅条件)的示例。从上可以看出这个订阅实际上设置了两组或运算的条件,其中第一组内又包含了两个与运算的条件。在
PredicateGroup表中的表现就是对应这个订阅的有两条uidPredicateORGroupID相同的记录,表示两组或运算条件,相应的uidPredicateANDGroupID字段对应到EqualsPredicates谓词表中,其中有一个对应两条记录,一个对应一条记录。

3.  消息订阅过程

下面的图是涉及到订阅部分数据库表的主要结构和相互关系。各字段的含义上面两节基本都有描述了。

深入biztalk消息以及消息订阅发布路由机制(二)-消息订阅_第2张图片
下面看一下
biztalk中两种订阅方式的各自如何产生订阅的:

3.1.              激活订阅

一般情况下,业务流程、发送端口和MSMQ这三类服务产生的订阅是激活订阅。这种订阅是被订阅的消息根据订阅条件新建订阅消息的服务主体,即新建一个服务实例,然后由这个服务实例处理订阅的消息,服务实例将消息处理完毕后,这个实例就算完成任务。

业务流程订阅一般表现形式是业务流程的接收端口跟物理端口绑定。其实它的订阅主体是这个业务流程的这个接收端口。条件是绑定的发送端口发送来的消息。

发送端口订阅一般可以是发送端口绑定到业务流程的一个发送端口。也可以是发送端口直接订阅由接收位置接收的消息,在发送端口的筛选器中可以根据消息的各种属性(包括系统属性和从schema升级的属性)来定义订阅的条件,比如某个消息的哪个升级属性大于某个值时。

以业务流程绑定一个物理接收端口为例说明:

业务流程跟一个物理接收端口绑定后,实际进行的操作是产生一个订阅。就是在Subscription表中生成一条记录表示订阅的主体,然后在一组谓词表中生成相应的订阅条件。

订阅主体就是这个业务流程的绑定的端口。在Subscription表中生成记录,字段uidClassIDXLANG/s业务流程服务的guid,表示订阅主体的服务类型是业务流程。uidServiceID字段是订阅的具体业务流程的guid(对应bts_Orchestration表)。uidPortID字段是这个业务流程中接收端口的guid(对应bts_orchestration_port表),uidPredicateGroupID字段是订阅谓词组id,表示跟这个订阅相关的谓词表中的记录。

订阅主体在Subscription表生成记录后,然后把订阅的条件要记入到相应的谓词表中。本例中端口绑定的情况,会产生两个条件,一个是接收端口id等于绑定的那个接收端口,形式为:http://schemas.microsoft.com/BizTalk/2003/system-properties. ReceivePortID == {9DB 16A 5F -ADD7-4CF2-9B 9A -D7924426DD18};另一个是消息类型是业务流程接收端口指定的消息类型,形式为:http://schemas.microsoft.com/BizTalk/2003/system-properties.MessageType == http://EAISchemas.Request#Request

这两个条件中都含有“system-properties”,表示是系统属性,这两个又都是等于条件,所以都记入EqualsPredicates谓词表中。所有的属性都有guid,系统属性有预设的guid,升级属性前面章节已经讲到,每个升级的属性都会生成一个guid(这就是为什么升级的字段可以用来路由消息,而可分辨字段不可以用来路由消息的原因,可分辨字段没有guid)。所以这两个条件在谓词表中的表现是,两属性guid代表的属性分别等于什么值。

3.2.              实例订阅

这种订阅由服务实例产生,并放入到订阅表中。当消息路由到消息队列后,会将订阅表中的实例订阅记录删除。

一般来讲Messaging Isolated(表示物理请求/响应类型的接收端口)这类服务会用到实例订阅,下面就这个为例说明:

请求/响应类型的接收端口,一般是由业务流程订阅这个端口的请求部分的消息,经过处理后返回消息,这个端口的的响应部分再订阅这个返回的消息,处理后返回给请求端。

请求部分的订阅是激活订阅,不再赘述。

响应部分是实例订阅,是由请求部分收到消息后新建Messaging Isolated服务实例后,这个服务实例在订阅表中建立的一个订阅,这个订阅其他部分跟激活订阅一致,就是在Subscription表中的uidInstanceID字段填入这个服务实例自身的guid,表示这是实例订阅,订阅主体就是这个服务实例。

当消息路由到这个实例订阅的消息队列后,这个实例订阅的使命就完成了,被从订阅表中删除,这个过程在下面消息的发布和路由中还有叙述。

4.  端口绑定的本质

端口绑定本质就是生成订阅,订阅服务器订阅发布服务器的消息,但是不表示这个发布服务器的消息只能给一个订阅服务器消费,一个消息可以同时被多个服务订阅,只要这个消息符合订阅条件,消息代理会把订阅把消息发送到所有订阅这个消息的服务实例。

 

你可能感兴趣的:(BI)