关于ESB的开发实践小结.docx

上传人:b****2 文档编号:894841 上传时间:2023-04-30 格式:DOCX 页数:14 大小:25.94KB
下载 相关 举报
关于ESB的开发实践小结.docx_第1页
第1页 / 共14页
关于ESB的开发实践小结.docx_第2页
第2页 / 共14页
关于ESB的开发实践小结.docx_第3页
第3页 / 共14页
关于ESB的开发实践小结.docx_第4页
第4页 / 共14页
关于ESB的开发实践小结.docx_第5页
第5页 / 共14页
关于ESB的开发实践小结.docx_第6页
第6页 / 共14页
关于ESB的开发实践小结.docx_第7页
第7页 / 共14页
关于ESB的开发实践小结.docx_第8页
第8页 / 共14页
关于ESB的开发实践小结.docx_第9页
第9页 / 共14页
关于ESB的开发实践小结.docx_第10页
第10页 / 共14页
关于ESB的开发实践小结.docx_第11页
第11页 / 共14页
关于ESB的开发实践小结.docx_第12页
第12页 / 共14页
关于ESB的开发实践小结.docx_第13页
第13页 / 共14页
关于ESB的开发实践小结.docx_第14页
第14页 / 共14页
亲,该文档总共14页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

关于ESB的开发实践小结.docx

《关于ESB的开发实践小结.docx》由会员分享,可在线阅读,更多相关《关于ESB的开发实践小结.docx(14页珍藏版)》请在冰点文库上搜索。

关于ESB的开发实践小结.docx

关于ESB的开发实践小结

关于ESB的开发实践小结

前言

  本指南描述了服务总线(AqualogicEnterpriseServiceBus---简称:

ESB)的一些典型使用场景、设计模式和实践经验。

同时对于ESB上一些常见的问题予以解答。

  本文的读者应该已经了解ESB的基础概念、进行了相关实践,以及熟悉ESB的管理配置界面。

使用流程元素

  ESB提供了丰富的消息流程处理的模型,可以有多种方式来实现。

因此需要有一个指导来表明在何时使用哪种方式比较适合。

何处执行转换(Transformations)

  路由节点(routenode)是消息流树上的一个页节点。

如果我们需要转换成或需要转换的消息格式依赖于目标服务,因此在路由节点(routenode)或发布节点(publishnode)中的请求/响应动作。

在发布节点的操作中,任何请求过程中的数据转换是发布动作目标服务所私有的。

换一种方式讲,当发布完成后,任何请求信息的改变会回滚到初始状态。

另一种请求动作是在outbound上下文变量($outbound)中设定控制变量来影响系统对于发送出去消息的操作(如:

设定服务质量QoS等)。

  如果转换是在消息请求(或消息响应)过程中执行,而不考虑路由终点,那么需要在请求(或响应)的管道中配置消息转换。

  例如,对于一个大批量的订单,需要对收到的SOAP报文生成一个订单汇总,并通过eMail发送给采购经理。

为支持这种场景,在请求管道中需要包含一个发布动作。

如果订单很大,请求动作需要将该订单转换成一个订单汇总,并将$attachments变量中的附件信息全部删除

  假设请求中附件信息的转换不需要理会最终的路由节点,因此建议在请求管道中的一个阶段(stage)将附件进行格式的转换。

  假设消息需要根据WS-addressing头信息路由到两个终点中的一个。

其中第二个终点(WebService)需要将SOAP消息体中的订单转换到一个新版本。

此时,路由节点需要进行条件路由,以将信息发送到两个终点中的一个,在第二个路由终点的请求动作中需要对订单信息进行格式转换。

另外,如果该服务采用的是JMS方式发送,还可以在$outbound变量中设定QoS为“exactlyonce”。

何时需要在消息流中使用分支

  如果一个代理服务提供的WSDL中包含多个操作,通常建议采用操作分支(operationalbranching)来对每个操作分别处理消息。

  如果一个代理服务的类型是AnySOAP或AnyXML,就需要在阶段动作中判断消息具体类型,然后需要一个条件分支(conditionalbranching),通过条件分支节点来根据消息类型路由消息。

  条件分支可以用于代理服务的最外层,来对外提供路由选择。

例如:

如果需要根据条件来调用服务A或服务B,上述动作如果不在路由节点中实现的话,就需要在消息流中配置条件路由。

在每个分支中使用路由节点作为其子节点,这是一种典型的决策方式,但如果消息分支数量比较多的时候,配置每个分支中子节点的路由就不能算是一个好的方案了。

设计单一或多阶段(StageAction)

  管道中单一的阶段通常能够满足大多数使用案例。

但是有些情况下,需要考虑多个阶段动作(stageaction)。

∙相比于把所有用户操作放置到一个阶段动作中,采用多阶段的设计模式提供了一个自然的模块化设计机制。

∙在请求或响应的管道中,每个阶段可以具有独立的差错处理能力。

当在管道中采用多个阶段操作,就可以避免在一个差错处理中来考虑各种动作所产生的差错处理。

∙如果使用了resume动作(在差错处理中)或skip动作,其行为是在请求/响应管道的下一个阶段恢复处理。

因此考虑到需要强调的业务逻辑,将resume动作或skip动作之后的动作放置到下一个阶段中是一个好的设计原则。

  在一个阶段中典型的动作包括:

1.消息的转换

2.消息汇报(reportaction)

3.通过一个循环,来进行WSCallout以进行消息的丰富或路由

4.校验消息是否合法和抛出错误提示

5.发布消息的副本到一个终点目标

何处处理差错

  ESB提供了三种差错处理的选择

1.在请求/响应管道中通过一个测试来校验。

如果断言是真,就通过reply动作(或replywithfailure)处理

2.在每个阶段层面、路由节点、管道节点或服务层等来捕获和处理消息

3.通过系统自带的差错处理机制来处理错误

  通常情况下,最容易的差错处理是在最低的级别进行捕获,使用高级别的差错处理来处理更普遍的差错。

但是对于inbound的WS-Security相关的差错只能在服务层进行捕获和处理。

  如果输入的消息是一种请求/响应型的消息,差错处理还需要包括产生应答消息通过replywithfailure动作发送回去。

在HTTP方式,replywithfailure会产生一个HTTP500状态信息。

而在JMS方式,replywithfailure会将JMS属性JMS_BEA_Error设置成为ture。

  如果服务是通过另外一个代理服务而调用的,其返回SOAP错误或传输错误,差错处理管道会被调用。

对于SOAP访问,如果replywithfailure动作被执行,则系统会将最初的SOAP错误会返回给调用者。

否则,系统错误处理机制会产生一个新的SOAP错误信息发送回去。

代理服务可以识别SOAP错误,但它通常是不需要检测消息(此种设计主要是考虑除非需要,可以尽量避免解析消息内容),因为HTTP返回状态设定的不是200和202,或者JMS属性JMS_BEA_Error设定为true。

而对于非SOAP的消息,JMS_BEA_Error=true也会被设定以标识这是一个差错响应。

  通常情况下,明确的对可预期的差错在管道之中进行处理是一个好的习惯,采用系统的差错处理机制只可用于不可预期的差错情况。

  某些用例调用会报告一个错误,使用报告(report)动作可以处理此场景。

例如:

当请求管道报告消息以便跟踪时,但在报告动作后,其路由节点中的服务调用失败,报告消息只能解析为消息已经被提交处理。

差错处理中的报告处理失败只能进行补偿操作,当有人在管理控制台中使用报告系统可以跟踪该消息,判断出最初提交的消息和其后续的差错表明该消息没有被正常处理。

判断使用何种类型服务

  服务总线支持各种类型的服务,包括WebServices(使用XML或WSDL中的SOAP绑定),以及各种非XML或其他通用的服务。

  如果一个服务具备一个定义良好的WSDL接口,使用WSDL来定义服务。

它具有以下可选的优势:

∙系统提供了对WSDL中每个操作的衡量

∙可以在管道中使用操作分支(operationalbranching)

∙当服务是被代理服务调用,SOAP动作的报文头会自动发布

∙在XQuery和XPath编辑器和条件构建器中,可以十分方便的操作$body变量,因为编辑器会自动将请求消息的$body消息映射到WSDL上。

但是,实际运行状态中$body信息内容可能对特定动作中会与缺省的内容有所不同。

这是因为服务总线是一种非传统的编程语言,它不会生命有类型的变量并使用。

相反其中的变量都是无类型的,并在运行状态时动态的创建和使用。

另外变量的类型会在创建时来表明变量所包含的内容。

设计时编辑器允许在一个指定动作中映射变量,依此简化XQuery的编写。

服务总线本身并不知道变量内容的类型。

∙如果服务使用WS-Security, WSDL是必须的(WS-Policies同时需要附在该WSDL上).

∙系统支持

这种WSDL语法,这可以动态的获得一个HTTP代理的WSDL,这对一些SOAP客户端代码生成工具是非常有用(如:

BEAWorkshop)。

  服务总线并不自动根据接口定义(WSDL或消息接口定义)来校验服务发送或接收的消息。

但是通过将服务接口定义放置到某一位置,在将来是可以通过打开开关方式来让系统对消息进行校验,虽然上述校验的代价比较大。

目前对于消息流的设计者使用校验动作和XQuery条件表达式来在消息流中进行明确的校验。

  服务总线不自动做必须理解的SOAP消息头的合法性校验,而是可以在消息流中通过Xquery明确的进行处理。

另外将来服务总线是可以增加选项来进行该项工作

  当使用WSDL,在下述场景中,建议选择WSDL Port方式来绑定服务而非直接绑定:

∙通过?

WSDL语法产生的WSDL中,port名称被保留,这对于一些客户端工具非常重要,但是服务的URL会被服务定义中transport部分的URL定义所覆盖。

绑定服务的WSDL中的URL不会被使用,除非它是在业务服务定义中缺省的URL定义

∙任何WS-Security策略在port层面被使用的状况下

  如果用户希望暴露一个port给客户端,以涵盖后端各种企业应用,可以使用AnySOAP或AnyXML服务类型。

  如果消息(请求/响应)中至少一个类型不是XML,则使用messagingservice类型定义服务。

对于各种类型的消息,如何理解上下文

  对于整个流程,存在一个消息,该消息存在于$header,$body和$attachments变量中。

即使服务类型不是SOAP方式,消息的规范模式遵循SOAP格式,在上下文中,消息的体现方式为SOAP格式。

  $header变量包含SOAPHeader元素,$body元素包含SOAPBody元素,而$attachments变量则封装了附件,每个附件为一个子附件元素。

附件元素包含body元素来表示真实的附件数据。

  如果消息格式是二进制格式,$body变量中的Body元素包含一个XML的指针元素,它表示二进制数据内容的指针。

而在二进制附件数据,附件元素中的body元素同样包含数据的指针信息。

  对于MFL格式的消息,$body变量中的Body元素则按照MFL文件所定义的XML格式体现。

  对于文本数据,$body变量中的Body元素为文本。

而对于文本格式的附件,$attachments变量中body元素为文本。

  对于XML格式的附件,$attachments变量中body元素为XML。

  下面给出了这些元素的格式定义,这些元素的命名空间为预先定义的”ctx”:

AttachmentsType"/>

--Eachattachmentinthe'attachments'variableisrepresentedbyaninstanceofthiselement-->

AttachmentType"/>

--Elementusedtorepresentbinarypayloadsandpass-byreferencecontent-->

BinaryContentType"/>

--the'attachments'variableisjustaseriesofattachmentelements-->

attachment"minOccurs="0"maxOccurs="unbounded"/>

--SetofMIMEheadersassociatedwithattachment-->

--Containstheattachmentcontentitself,eitherin-linedoras-->

--URIreferencetothebinaryorpass-by-referencepayload-->

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

∙当在一个Xquery中指向一个变量时,该变量的根元素通常没有表达出。

例如:

一个Xquery的表达式需要获取第一个附件的Content-Description信息,可以表达为:

$attachments/ctx:

attachment[1]/ctx:

Content-Description.

另一个Xquery示例是获取第二个附件中的订单信息,这样订单的获取为:

$attachments/ctx:

attachment[2]/ctx:

body/*

∙当变量为空或只有一个元素,而Xquery返回的是一个序列信息,则当该Xquery被赋给该变量时,只有序列中的第一个元素被存入该变量。

例如:

如果需要将WS-AddressingMessagerIDSOAP头赋予一个变量,而SOAP头只有一个的情况下,赋值动作为:

assigndata($header/wsa:

MessageID)tovariableidvar.

注意:

如果有两个WS-AddressingMessageID头存在,变量中只包含第一个头的信息。

∙通常情况下,当使用转换资源(XSLT或XQuery),转换资源需要定义转换SOAP报文体的文档,为了简化,转换的输入参数仍然可以是一个XQuery,例如输入参数可以从$body变量中选择是$body/*[1]来提供业务文档,转换的结果通过替换内容动作可以直接放置到$body中(替换$body变量的内容意味着替换Body元素的内容)。

采用这种方式会使转换更有效率。

∙当XQuery表达返回序列,可以通过插入和替换操作可以实现对一个序列的插入和替换。

例如:

将$inbound变量中的transportheader信息复制到$outbound变量中。

复制JMS属性

  服务总线设计是考虑到代理服务的接口和调用的业务服务的接口是不同的情况。

因此,缺省它不会从输入消息的上下文复制任何信息到输入信息的上下文中(例如:

transportheader和JMS属性)。

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

  例如:

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

  Insert$inbound/ctx:

transport/ctx:

request/tp:

headers/tp:

user-headerasfirstchildof./ctx:

transport/ctx:

request/tp:

headersinvariable$outbound.

传输保障

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

  对于ESB而言,只有当输入请求的传输协议是基于XA连接工厂的JMS方式,而且输出服务的QoS(QualifyofService)设定为exactlyonce(此种场景下的缺省配置),系统才实现消息的可靠传递机制。

而对于其他场景下,消息可能会丢失或多次传递。

在$outbound变量中指定的QoS通常只是一个暗示,表明希望能够实现可靠传递。

对于exactlyonce这种服务质量的实现,系统会尽可能实现exactlyonce的传输保障,其次它会尽可能提供atleastonce的传输保障,最后是没有任何传输保障的方式。

而此处所指的传输保障会有详细的描述。

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

  如果一个路由节点或发布节点的输出传输协议为JMS/XA,那么系统会确保消息从输入通道到输出通道的过程中只传送一次,同时保障传输中消息不丢失或重复。

而对于其他的传输协议(如:

email,FTP,file,HTTP,HTTPS,JMS/nonXA),系统会确保消息从输入通道到输出通道的过程中传送至少一次,同时保障消息的不丢失。

  而对于HTTP(S)协议的消息传输至少一次还需要进一步的考虑。

即使目标服务响应(正确的HTTP状态应答或错误应答),传输过程被认为已经结束。

这是因为目标的服务已经返回信息,尽管是验证错误或者页面没有找到,这表明目标服务所在的Server是可用的,而且服务是有可能可以处理其他消息的。

如果消息传输过程中,代理服务器或者目标服务器宕机,则目标服务不在或者响应实践超时,则消息会重新传递。

  消息重发是基于输入的JMS。

重试的次数以及如果次数到了之后的处理可以在WebLogicServer的控制台中配置(并不在ServiceBus的sbsoncole中配置)。

缺省的,服务总线创建的消息队列,其重试次数为1,当重试次数到了之后,消息会被抛弃掉。

发送消息的重试

  除了输入JMS消息之外,还可以对目标服务访问配置重试和负载均衡。

负载均衡和容错,以及重试连接的目的是为了提供高效访问和高可用性支持。

对于每个消息,URL列表会根据负载均衡的算法自动排列到容错处理的队列上。

如果服务结束前,配置的访问重试的次数为N,如果出现状况,整个访问系列会重试N次,而在每次重试访问之前,会等待所指定的重试间隔。

当所有尝试结束,如果仍存在错误,对于路由节点的差错处理管道会被调用以进行后续处理。

  对于HTTP(S)协议,任除了200和202之外的任何HTTP状态都会被认为是错误,并会重试。

服务总线的错误处理机制的设计是尽量简化、统一和安全的,因此在这样的设计算法下,服务总线对于认证错误之类应答在一段时间范围内是不会矫正该URL,另一方面,ALSB如果对于后续的访问转发的其他URL上,而新的URL也许不会产生类似的错误应答。

内容类型、JMS类型和编码

  为了方便的与异构系统的互操作性,用户可以控制消息所使用的内容类型(contenttype),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“以保障传输HTTPPOST请求到目标业务服务上。

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

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

 

异步请求/响应

  一个通用的场景是客户调用了一个代理服务,如WebService或HTTP,而该WebService后台所调用的系统提供的是JMS请求/响应。

这种场景称为同步转异步过程。

反之亦然,称为异步转同步过程。

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

∙请求线程不会被挂起等待应答,因此消除了请求应答阻塞的线程管理情况。

因为ESB充分利用了Weblogic提供的Work Manager处理机制,具体可以WebLogicWorkManager相关文档

∙使消息的传输更加可靠

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

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

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

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

  对于一个使用JMS方式在ServiceBus上交互的请求和应答消息,必须通过JMSCorrelationID属性相互关联。

换句话说,所实现的业务服务中,在接收消息时必须需要使用getJMSCorrelationID获取JMSCorrelationID,而在消息发送到queue或topic之前,需要通过setJMSCorrelationID 来设定JMSCorrelationID。

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

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

  StringgetJMSCorrelationID():

该方法返回JMScorrelationID的值,可能是提供者专用的消息ID或是应用指定的String.

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 临时分类 > 批量上传

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2