技术开发 频道

关于ESB的开发实践小结


    上下文实际处理过程中的一些关键点

    当在一个Xquery中指向一个变量时,该变量的根元素通常没有表达出。例如:一个Xquery的表达式需要获取第一个附件的Content- Description信息,可以表达为:$attachments/ctx:attachment[1]/ctx:Content- Description.
另一个Xquery示例是获取第二个附件中的订单信息,这样订单的获取为: $attachments/ctx:attachment[2]/ctx:body/*

    当变量为空或只有一个元素,而Xquery返回的是一个序列信息,则当该Xquery被赋给该变量时,只有序列中的第一个元素被存入该变量。例如:如果需要将WS-Addressing MessagerID SOAP头赋予一个变量,而SOAP头只有一个的情况下,赋值动作为:

    assigndata($header/wsa:MessageID)to variableidvar.

    注意:如果有两个WS-Addressing MessageID头存在,变量中只包含第一个头的信息。

    通常情况下,当使用转换资源(XSLT 或 XQuery),转换资源需要定义转换SOAP报文体的文档,为了简化,转换的输入参数仍然可以是一个XQuery,例如输入参数可以从$body变量中选择是$body/*[1]来提供业务文档,转换的结果通过替换内容动作可以直接放置到$body中(替换$body变量的内容意味着替换Body元素的内容)。采用这种方式会使转换更有效率。
当XQuery表达返回序列,可以通过插入和替换操作可以实现对一个序列的插入和替换。例如:将$inbound变量中的transport header信息复制到$outbound变量中。

    复制JMS属性

    服务总线设计是考虑到代理服务的接口和调用的业务服务的接口是不同的情况。因此,缺省它不会从输入消息的上下文复制任何信息到输入信息的上下文中(例如:transport header和JMS属性)。

    代理服务请求和响应的transport headers 是存储于$inbound,而调用业务服务请求/响应的transport header存于$outbound变量中。

    例如:对于单向的消息(交互而不需响应)的情况,XQuery可以将用户定义的JMS属性 从$inbound复制到$outbound:

    Insert$inbound/ctx:transport/ctx:request/tp:headers/tp:user-headeras first child of./ctx:transport/ctx:request/tp:headersin variable$outbound.

    传输保障

    很多情况下,用户在使用产品时,需要了解该产品支持那种类型的消息可靠传递机制。

    对于ESB而言,只有当输入请求的传输协议是基于XA连接工厂的JMS方式,而且输出服务的QoS(Qualify of Service)设定为exactly once (此种场景下的缺省配置),系统才实现消息的可靠传递机制。而对于其他场景下,消息可能会丢失或多次传递。在$outbound变量中指定的QoS通常只是一个暗示,表明希望能够实现可靠传递。对于exactly once 这种服务质量的实现,系统会尽可能实现exactly once 的传输保障,其次它会尽可能提供at least once的传输保障,最后是没有任何传输保障的方式。而此处所指的传输保障会有详细的描述。

    对于使用场景(请求输入为 JMS/XA 而 QOS = exactly once),传输保障的提供机制如下:

    如果一个路由节点或发布节点的输出传输协议为JMS/XA,那么系统会确保消息从输入通道到输出通道的过程中只传送一次,同时保障传输中消息不丢失或重复。而对于其他的传输协议(如:email, FTP, file, HTTP, HTTPS, JMS/nonXA),系统会确保消息从输入通道到输出通道的过程中传送至少一次,同时保障消息的不丢失。

    而对于HTTP(S)协议的消息传输至少一次还需要进一步的考虑。即使目标服务响应(正确的HTTP 状态应答或错误应答),传输过程被认为已经结束。这是因为目标的服务已经返回信息,尽管是验证错误或者页面没有找到,这表明目标服务所在的Server是可用的,而且服务是有可能可以处理其他消息的。如果消息传输过程中,代理服务器或者目标服务器宕机,则目标服务不在或者响应实践超时,则消息会重新传递。

    消息重发是基于输入的JMS。重试的次数以及如果次数到了之后的处理可以在WebLogic Server的控制台中配置(并不在Service Bus的sbsoncole中配置)。缺省的,服务总线创建的消息队列,其重试次数为1,当重试次数到了之后,消息会被抛弃掉。

    发送消息的重试

    除了输入JMS消息之外,还可以对目标服务访问配置重试和负载均衡。负载均衡和容错,以及重试连接的目的是为了提供高效访问和高可用性支持。对于每个消息,URL列表会根据负载均衡的算法自动排列到容错处理的队列上。如果服务结束前,配置的访问重试的次数为N,如果出现状况,整个访问系列会重试N次,而在每次重试访问之前,会等待所指定的重试间隔。当所有尝试结束,如果仍存在错误,对于路由节点的差错处理管道会被调用以进行后续处理。

    对于 HTTP(S) 协议,任除了200和202之外的任何 HTTP状态都会被认为是错误,并会重试。服务总线的错误处理机制的设计是尽量简化、统一和安全的,因此在这样的设计算法下,服务总线对于认证错误之类应答在一段时间范围内是不会矫正该URL,另一方面,ALSB如果对于后续的访问转发的其他URL上,而新的URL也许不会产生类似的错误应答。

    内容类型、JMS类型和编码

    为了方便的与异构系统的互操作性,用户可以控制消息所使用的内容类型(content type),JMS类型以及编码类型。这是一个通用的使用状况。

    服务总线避免在服务定义时,对于外部客户或服务需要或使用信息配置进行假设。这最大化保证客户可以与各种不同的端点服务之间的互操作性。

    服务总线继承服务类型或接口调出消息的内容类型。内容类型是email或HTTP(S)协议的一个组成部分。

    如果服务类型是XML或SOAP(有WSDL或没有),内容类型是text/xml
    如果服务类型是消息方式或其接口为MFL或二进制,册内容类型为binary/octet-stream。
    如果服务类型为消息方式。而接口为文本,则内容类型为text/plain。
    如果服务类型是消息方式,而接口格式为XML,则内容类型为text/xml。

    在代理服务调用一个业务服务时,内容类型可以在输出上下文变量中覆盖,也可以是代理服务应答时,覆盖输入上下文变量中所设定的内容类型。例如:用户可以通过设定outbound-request的Content-Type为“application/x-www-form- urlencoded“以保障传输HTTP POST请求到目标业务服务上。

    对于JMS,除了二进制和文本,还有一个例外,JMS的类型可以在服务定义时候明确配置。

    同样的,编码也可以在服务定义时,对调出消息的编码明确指定。

    异步请求/响应

    一个通用的场景是客户调用了一个代理服务,如Web Service或HTTP,而该Web Service后台所调用的系统提供的是JMS请求/响应。这种场景称为同步转异步过程。反之亦然,称为异步转同步过程。

    使用异步请求响应方式可以提供:

    请求线程不会被挂起等待应答,因此消除了请求应答阻塞的线程管理情况。因为ESB充分利用了Weblogic 提供的Work  Manager处理机制,具体可以WebLogic Work Manager相关文档

    使消息的传输更加可靠

    对于使用消息总线之类的产品,如MQ,以实现诸如与大机之类的系统进行交互的过程。

    另一个要点是,异步服务需要一个关联ID(correlation  ID)来提供应答,关联ID格式通常是一个内部格式,可以兼容如MQ或者是目标服务所使用MQ 本地接口。

    异步请求/应答模式是被输出传输通道所控制,消息流程(除了$outbound 变量中transport所指定的数据)是并不了解JMS请求/应答和HTTP请求/应答这两种服务之间的区别。

    使用JMS  Correlation ID关联请求和响应的消息

    对于一个使用JMS方式在Service Bus上交互的请求和应答消息,必须通过JMS Correlation ID属性相互关联。换句话说,所实现的业务服务中,在接收消息时必须需要使用getJMSCorrelationID获取JMS Correlation ID, 而在消息发送到queue或topic之前,需要通过setJMSCorrelationID  来设定JMS Correlation ID。

    消息接口(javax.jms.Message) 是所有JMS消息的根本接口,JMS消息头包括了JMSCorrelationID 属性字段来关联不同的消息,JMSCorrelationID 可以保存一个提供者专用的消息ID,或应用专用的string对象或者byte[]值。

    在接收消息前,可以获取 JMSCorrelationID,发送消息前进行设定:

    String getJMSCorrelationID():该方法返回JMS correlation ID 的值,可能是提供者专用的消息ID或是应用指定的String.

    void setJMSCorrelationID(String correlationID):该方法用于设定JMS CorrelationID

    而如果后端消息处理系统为MQ Series,或者其他的JMS服务器,需要遵循该消息处理器所提供的消息关联机制,来设定消息关联的ID。例如,如果消息服务提供者为MQ Series,其消息ID关联的属性字段为MessageID,相应的Java实现接口也变为对MessageID属性的Get和Set操作了。

    动态路由

    在代理服务无法确切的了解哪个服务被调用,但知道接口的类型,而服务的调用是在输入的消息中所指定(服务接口类型可以被抽象化:命名消息类型、port类型和绑定信息,除了具体接口定义。具体的接口定义是表示服务具体位置的transport URL)

    此种场景下,实现机制是注册一个接口定义的业务服务(而transport URL的定义可以无关),流程中的路由或发布节点中,增加一个动作设定$outbound变量中的服务的URL信息,调用具体的服务,这可以使URL信息可以在运行状态时提供,而无需在设计时指定。

    操作Weblogic 8.1的回调

    Weblogic 8.1 提供一个所谓回调的概念。通常,具有回调接口的WSDL提供一个回调通知或具体的应答操作方法。回调地址在请求消息中的SOAP头中包含。

    为了支持与WebLogic Platform. 8.1上的服务的互操作性,用户可以进行如下配置:

    将具有回调的WSDL 的port type/binding 分拆成两个port types/bindings --- 一个是消息接收(请求的 port type),而另一个是服务回调方的回调(callback port type)。通知操作(Notification)可以成为一个新的单向操作,而具体的应答转变成为一个请求/响应的操作,服务总线提供了分拆WSDL的功能选择。

    基于请求的request porttype.  定义业务服务

    基于callback porttype 定义回调服务,具体的URL并不重要(可以参考上一节的动态路由)

    使用请求类型(request port type)定义代理服务 (Proxy_R),并路由到请求的业务服务上

    使用callback port type定义回调的代理服务(Proxy_C)。并路由到回调的业务服务上。

    在Proxy_R 的请求处理中,从SOAP头中获取回调的URL地址,并替换为 Proxy_C服务所提供的URL。这可以使请求的业务服务知道从该向哪里发起回调服务调用。流程中增加一个变量用于存储该URL,我们称之为回调URL (callback_URL),保存从Proxy_R SOAP请求中的SOAP头中的回调URL地址,这可以保障在Proxy_C服务执行时,它清楚该最初的URL地址,以便回调时可以找到。这样服务总线无需保存状态(服务总线是一个无状态的架构)。例如:传输给请求业务服务的回调地址为: http://Proxy_C?CallbackURL=” http://callback_URL”

    在 Proxy_C中,它首先从$inbound变量中获取参数,解析并抽取出callback URL参数,并在调用真正的回调服务时,在$outbound变量中进行设定,此时系统可以动态的路由回调到最初请求所指定的回调URL上。

    使用 WSCallouts

    服务总线关注于各种不同传输协议之间的路由消息,同时在处理过程中保障安全和格式转换。因此它并不真正适合创建复杂的消息,服务协调和服务数据的汇总。BEA的其他产品如:Aqualogic Data Service Platofrom或WebLogic Integration更加适合。服务总线的代理服务可以调用Liquid Data 服务或workshop开发的JPD,反之,Data Service或JPD也可以调用服务总线的代理服务。

    WScallouts 提供了服务协作、组装和数据汇总的服务调用功能。但WScallouts的基本使用场景是:

    消息验证:调用web service来进行消息格式校验,例如对于订单可以判断其是否能执行订单处理。
    消息格式丰富:调用web service来丰富消息的格式,以便路由节点所调用的服务能正常处理该消息。
    消息的转换:调用web service来通过相关转换引擎进行格式转换
    消息路由:调用web service 来传递相关参数,以便决定该向哪类服务进行路由

0
相关文章