JBI规范-规格化消息路由NMR(一)
规格化消息路由从JBI组件(服务殷勤或绑定组件)接收消息交换ME并将其路由到适当的组件进行处理。[This
mediated message-exchange processing model decouples
service consumers from providers, and allows the NMR
to perform additional processing during the lifetime
of the message exchange.]
本章中使用WSDL2.0中的术语而不是WSDL1.1。
1.几个关键的概念
本节介绍NMR架构中的几个关键概念。NMR的目标是[The goal of the NMR is to
allow components acting as service producers and consumers
to interoperate with one another in a predictable fashion,
using WSDL-based service descriptions as the sole source
of coupling between them. This is key to allowing mix-and-match
assembly of components, creating the basis of integration
solutions and a services infrastructure.]
WSDL [WSDL 2.0, WSDL 1.1]为JBI组件交互提供了基本的模型和描述机制。WSDL提供了一个基于XML消息交换操作的抽象服务模型,该模型可以通过提供特定的绑定信息(将抽象模型映射到实际的通信模型和端点[WSDL
2.0 bindings] 的特定的协议信息)进行扩展。
JBI扩展应用了WSDL的抽象消息模型,可以把NMR看作是一个抽象的WSDL消息系统基础平台[infrastructure],绑定组件和服务引擎在这个平台上提供和使用WSDL定义的服务。
WSDL定义了一项服务提供者和消费者之间的消息交换操作,消息交换参与者依照各方都能够理解的一种消息交换模型进行操作。一组相关联的操作称作“接口”,该接口的实现称作“服务”。一个服务具有一个或多个端点,每个端点通过一种特定的绑定(消息通信协议)为外部系统访问该服务提供入口。
所有的这些WSDL概念都被JBI用于APIs和SPIs中构建服务模型。
1.1. 服务消费者和提供者
JBI引擎和绑定组件可以扮演服务消费者,服务提供者或两者兼之的角色。服务提供者通过端点(endpoint)提供WSDL描述的服务;服务消费者通过开始调用特别操作的消息交换使用服务。服务(service)实现了WSDL的接口,WSDL接口是通过交换抽象定义的消息来描述的一组相关的操作。
因为服务消费者和服务提供者之间通常只共享抽象的服务定义而不是具体的端点信息,所以两者之间是松耦合的。这种结构使得服务提供者的具体实现(如特定协议)对服务消费者来说是透明的。
一个WSDL接口可以具有多个服务实现,服务消费者在查找实现了某个接口的提供者时,可能查找到多个实现了该接口的服务提供者(服务和相关联的端点)。
1.2. 规格化消息
JBI使用“规格化(normalized)”消息的概念描述服务消费者和提供者之间的交互。一条规格化消息由如下三个主要部分组成:
- 消息载荷(payload):符合抽象WSDL消息类型,不具有任何协议编码或格式信息的XML文档(这不是一个消息的规范格式)。
- 消息属性(或元数据):包含了在消息处理过程中获得的与消息相关的额外信息。消息属性可以包含消息的安全信息(例如消息接收方的签名信息),事务上下文信息和组件特定的信息。
- 消息附件:消息载荷的一部分可以由附件构成[A portion of the content of
the “payload” (content) of the message can be made
up of attachments, referenced by the payload, and
contained within a data handler that is used to manipulate
that contents of the attachment itself. Such attachments
can be non-XML data.]
规格化消息通过抽象WSDL消息类型定义为组件间的交互提供了互操作。
1.3. 传输通道(Delivery Channel)
传输通道是绑定组件和服务引擎与NMR之间通信使用的双向通信管道。传输通道构成了服务消费者,提供者和NMR之间的交互契约,即API接口。服务消费者使用传输通道开始服务调用,服务提供者使用传输通道从NMR接收服务调用。既能发起调用服务,又能接收服务调用的组件使用同一个传输通道完成这两种功能。
以一个绑定组件接收JBI系统外部的服务消费者请求为例,当接收这种传入的服务调用请求后,该绑定组件通过其传输通道与NMR交互时必须扮演服务消费者的角色(在此场景中,绑定组件可以看作是一个服务消费者代理)。
每个组件都具有唯一的一个传输通道,因此传输通道的实现必须支持在多线程环境下的并发使用。
1.4. 运行时端点激活
运行时激活是服务提供者激活其提供的实际的服务的过程,在该过程中,服务提供者将其实际的服务注册到NMR,使得NMR可以将调用路由到该服务。端点激活分为两步:
- 向NRM声明一个服务端点
- 提供描述该端点定义的元数据信息
向NRM声明一个服务端点是绑定组件或服务引擎向NMR注册一个端点名称的过程。在NMR中声明的端点名称必须有相应的元数据信息详细描述该端点的注册,这部分详细信息在作为组件接口一部分的SPI中进行了详细的描述。
1.5. 服务调用和消息交换模型
服务调用指服务消费者和服务提供者之间的一个端对端交互的实例。尽管无法在JBI中定义一套完整的服务调用模型,但是JBI实现必须支持如下列表中的交互模式:
- 单向交互(One-Way)模式:服务消费者向提供者发送一个请求,服务提供者不必向消费者返回任何错误信息。
- 可靠的单向交互(Reliable One-Way)模式:服务消费者向提供者发送一个请求,如果服务提供者处理该请求失败,它可以向消费者返回处理的错误信息。
- 请求-回复(Request-Response)模式:服务消费者向提供者发送一个请求,并期望服务提供者返回一个处理应答,如果处理失败则返回处理的错误信息。
- 请求-选择回复(Request Optional-Response)模式:服务消费者向提供者发送一个请求,并期望服务提供者返回一个处理应答,如果处理失败则返回处理的错误信息;如果服务消费者处理返回的应答失败,则向服务提供者发送应答处理错误的信息。
上述提到的消费者和提供者角色可能由绑定组件或服务引擎来扮演。当一个绑定组件扮演一个服务消费者的角色时,也就说明存在一个外部的服务消费者;同样的,当一个绑定组件扮演服务提供者角色时,也就说明存在一个外部的服务提供者。当以任意一种角色使用服务引擎时,说明该服务引擎是一个内部参与者。
WSDL 2.0预定义扩展[WSDL 2.0 Extensions]定义了一个消息交换模型(MEP),JBI使用该模型定义消费者节点和提供者节点之间的交互。该模型根据消息类型(normal或fault)和消息流向定义。
MEPs总是站在提供者的角度来理解。例如,在请求回复交互模式中, MEP的定义是in-out,站在提供者的角度来看,请求(Request)是输入(in),回复(Response)是输出(out)。从服务消费者的角度看,消息流的方向正好相反,但是NMR在与服务消费者交互过程中使用的MEP总是从服务提供者的角度来说的。当处理WSDL
MEPs时,这是一种惯用的处理方式。In-Out模式示意图如下所示:
如上图所示,第一条消息(请求)是从消费者发送到提供者,从提供者的角度看其方向是输入(in)。第二条消息(回复)是从提供者到消费者,即输出(out)。这些交换是按给出的序列执行的,从提供者的角度这种交换首先是输入一条消息(in),跟着是输出(out)一条消息,因此这种交互模式命名为输入输出(in-out)模式。
1.6. 消息交换(Message Exchange)
消息交换(ME)用作承载构成服务调用一部分的规格化消息的“容器(container)”。ME不仅封装了其实现的消息交换模型中的输入(in)消息和输出(out)消息,它还包含了这些消息的元数据信息以及正在进行的消息交换的状态信息。消息交换代表了JBI本地服务调用的一部分。下表说明了服务调用和消息交换模型之间的关系:
服务调用(Service
Invocation) |
消息交换模式MEP
(提供者角度) |
One-Way |
In-Only |
Reliable One-Way |
Robust In-Only |
Request-Response |
In-Out |
Request Optional-Response |
In Optional-Out |
表 2 Service Invocation to MEP Mapping
图One-way Service Invocation Between two Service Engines
上图描述了两个本地服务引擎间的单向服务调用:SE1作为一个服务消费者,通过创建并初始化一个包含了消息请求的in-only消息交换调用所需要的服务操作。如上图中的连接线流向所示,SE1将该消息交换实例发送到NMR。
NMR根据该消息交换实例决定由哪一个服务提供者提供该消息交换请求的服务操作,并将其传输给选定的提供者。该对象流转过程从上图NMR和SE2
之间的连接线可以看出。
需要注意的是该图示并不意味着调用方必须在交换完成之前阻塞当前线程的执行。调用方在发送和接收消息时,可以是事件驱动[as
shown in the activity diagram, advances the engine’s
internal state without necessarily tying up thread resources.]
图SE Invokes Service Provided by Remote JBI Instance:
Robust In with Fault Normalized
以下内容描述了上图所示的处于两个不同的JBI环境中的服务引擎之间的可靠的单向调用逻辑。需要注意的是规范中未规定如何联合两个分离的JBI实例,该例中两个JBI实例之间通过BC1和BC2提供的通信协议使得两者作为远程的消费者和提供者而相互可见,并不存在影响两者之间调用执行的特殊关系。
SE1构建并初始化了一个可靠的单向(robust-in)消息实例,并发送到NMR(在构建ME实例的过程中,NMR为该实例设定了一个唯一标识“X”)。NMR选择合适的服务提供者,并将消息交换以可靠的单向消息模式发送给BC1。BC1按照其所实现的协议需求封装消息请求,并将该请求发送给服务提供者,在本例中,恰好是另一个通过BC2发布了一个服务端点的JBI实例JBI2。
当JBI2实例中的BC2组件接收到请求以后,该组件构建一个可靠的单向消息交换实例(“Y”)并发送给NMR。JBI2实例中的NMR选择合适的服务提供者并将消息交换实例(“Y”)发送给该提供者即SE2。
SE2接收实例“Y”,处理完成以后,SE2可能选择返回一个故障消息说明发生了一个应用级别的错误。在本例中,SE2可以使用实例“Y”返回故障消息,沿着请求流向的反向路径最后通过消息交换实例“X”到达JBI1实例中的SE1组件(在此MEP中,存在一个“done”响应信息会沿着相同的路径传递,为了清晰未在图中显示)。
以下内容描述了上图所示的JBI实例中的服务引擎与JBI系统外部的一个远程服务提供者之间的请求/响应调用。
服务引擎SE创建并初始化一个in-out模式的消息交换实例并发送到NMR,由NMR决定哪一个服务提供者应当处理该调用。在本例中,BC组件被选中,BC接收到该消息交换(in-out模式),将其反规格化(denormalize),然后通过通信协议发送到外部的服务提供者。外部提供者处理消息请求,返回适当的信息(正常的回复或者是应用处理层级的错误消息)。BC组件规格化该回复,讲求封装到消息交换,然后发送到NMR,最终返回给消费者SE。
1.7. 端点(Endpoints)
端点,在WSDL2.0中指代一个可以通过特定协议访问的特定的地址,用于访问特定的服务。JBI使用这个概念表示两种不同类型的端点:
- 外部端点:JBI系统外的端点。外部服务提供者发布的端点,绑定组件发布的端点,用于代理外部服务消费者。
- 内部端点:JBI系统内部服务提供者发布的端点,可以通过NMR的API访问。
绑定组件在内部端点和外部端点之间建立映射,例如,绑定组件提供的内部端点可以映射到外部服务提供者发布的端点。
在JBI中,端点可以通过三种不同的方式进行引用:
- 隐式引用:JBI根据服务类型选择服务提供者端点
- 显式引用:服务消费者使用自身的逻辑或配置选择服务提供者端点
- 动态引用:在消息交换中使用一个端点引用(EPR)来提供“回调”地址供服务提供者返回应用会话进行过程中其它相关的消息交换信息。EPR在JBI中具有两种不同的使用方式:
a) EPR构建(EPR creation):一个组件希望在消息中提供回调地址时,必须能够构建适当的EPR。
b) RPR解析(EPR resolution):一个接收EPR的组件必须能够解析该EPR(也就是将其转换成可用的端点)以便于将消息交换发送到适当的端点(通常是外部服务提供者)。
2. 消息交换的构成
- 模式(Pattern):每条消息交换都通过消息交换的模式(方向,序列,cardinality)和消息名称(normal或fault)构成。
- 起始组件(Initiator):构建该消息交换的组件。在所有JBI定义的消息交换模式中服务消费者组件担当消息交换的初始组件。
- 服务组件(Servicer):处理该消息交换的组件。服务提供者担当服务组件。
- 角色(Role):当一个组件“拥有”某条消息交换时,该组件所扮演的角色,包括:提供者—提供该消息交换请求的服务;消费者—该组件向提供服务的提供者发出请求。
- 地址(Address):一个服务引用,端点引用和NMR用来路由消息的逻辑地址的操作名称。
- 消息(Message):携带一条或多条消息的消息交换ME。
- 故障(Fault):携带至多一条故障信息的消息交换,错误是一种特殊的消息。
- 状态(Status):描述消息交换的状态:error,done或active中的一种。
- 错误(Error):用于描述错误状态原因的Java Exception对象。
- 属性集(Properties):消息构建组件和消息服务组件可以将任意的属性信息关联到其拥有的一条消息交换ME。NMR可以预留某些属性名称用于声明QoS,安全,事务或其它操作元数据。
消息交换的生命周期很短,不能够在系统停止或崩溃时保留。由消费者和提供者组件提供的错误恢复逻辑必须处理这类错误案例。能够使JBI支持可恢复性的可靠的消息交换需求将在JBI2.0中进行考虑。
2.1. 交换概要(Exchange Summary)
下表是JBI使用的WSDL2.0中定义的消息交换模式。每种定义包含一个故障处理规则,用于[which
specifies which message in the exchange is created (or
replaced) to convey a fault from one participant to
the other.],能够与WSDL1.1等同的操作也同时在表中列出。
Pattern Name |
Message Sequence |
Fault Rule |
WSDL 1.1 Operation |
In-Only |
in |
none |
One-way |
Robust In-Only |
in |
on in |
- |
In-Out |
in, out |
replaces out |
Request-response |
In Optional-Out |
in, out |
on in or out |
- |
表 3 JBI Standard Message Exchange Patterns (from WSDL
2.0)
3. 规格化消息
规格化消息是JBI消息交换ME中的消息。本节定义了规格化消息,同时讨论了JBI中处理该类消息的模型。
3.1. 标准化定义
消息的规格化指的是将协议与业务上下文信息以可传输的方式存储起来的过程。NMR处理的所有消息都是规格化的,规格化是一个双向的过程:
- 消息的规格化是将包含了特定上下文数据的消息转换成上下文中立的抽象表示,本质上说就是将由NMR解释的上下文数据转换成一种NMR能够理解的“通用”的表现形式。任何其他的信息(如消息载荷,附加上下文等)都可以由消息承载并由NMR传递,但是,这些信息对NMR来说是透明的。需要说明的是规格化并不意味着要将消息载荷数据规范化表示。
- 反规格化消息指的是从NMR接收消息并将其转换为与上下文相关的表现形式。反规格化是规格化的逆向操作,例如,一个SOAP绑定组件反规格化消息时会将消息适当的部分以及消息元数据放入SOAP信封,转化成需要的编码格式。
3.2. 规格化消息的结构
规格化消息包含两个不同的部分:上下文和载荷。
消息上下文指的是一组消息属性集,可以为消息关联一些元数据信息。
消息载荷实际上是包含了所有消息载荷的原始数据信息的抽象。在此处,术语包含(“contain”)是指包含在描述消息的抽象数据模型中。
3.3. 处理方法
规格化消息提取并未规定消息载荷的处理方式。消费者可以根据特定上下文需求自由选择消息载荷的处理方式。例如,一个高性能的绑定组件会考虑使用“拉”模式的解析器或原始字节流来序列化消息载荷;另一方面,一个转换引擎可能需要将整个消息载荷加载道内存中表示成XML的DOM树以便于查询。
3.4. 二进制数据
规格化消息的消息载荷一定是XML,对于非XML(包括二进制数据)的数据通过使用JAF(Java Activation
Framework)将这些数据作为规格化数据的附件。
3.5. WSDL1.1的支持
服务提供者可能使用WSDL1.1描述其自身而不是用WSDL2.0。由于WSDL1.1的消息模型与2.0有很大的区别,JBI定义了一个映射关系用于将WSDL1.1消息映射成为单个XML文档的规格化消息形式。
|