打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
ESB之旅(关山何止千万重——ErrorHandler、LoanBroker)

 

有人说白人的傲慢是浸透在骨子里的,虽然表面看不出来,也许再待的时间长点我对此能有些体会,到时候再告诉大家。可是即便那样,Q和我也是可以忍受的。穷人到哪里都是穷人,Q和我都出生在国内贫穷落后的小城市,依靠自己的努力考上像样的大学,硕士毕业来到某直辖市,并得到当地的户籍,但始终无法融入当地人的生活,待了几年也没有学会直辖市人引以为傲的方言,一口普通话也让我们受到过不少的区别对待。所以我喜欢那篇文章——《我花了18年的时间才能和你坐在一起喝咖啡》,其实我们花的时间何止18年?何必说人家有种族优越感,即便在国内,对待自己的同胞,某些人又何尝有过平等的心态?Q和我,不过是这艰难时世中的一对凤凰男和凤凰女,努力寻找着可以挡风遮雨的一棵梧桐树罢了!——《关山何止千万重》

  天涯上一篇帖子里的文字,就扔这了。

  突然就想到一个问题:现在骡子这个东西早就绝种了吧?现在的马是比赛用的,驴也很罕见了,可能就剩点可可西里的野驴了,更别提骡子了,况且骡子不能生育,岂不是死一个少一个...

  Scripting 演示mule对JSR-223的支持,先略过不表,error handler例子过一下,重点分析loanBroker例子。

 

一、Error Handler (演示了如何使用Spring beans作为service component以及向多个出站endpoint发布消息,使用了文件监控inbound+邮件outbound)

  1、示例翻译:

  示例包含两个services: ExceptionManager异常管理器 和 BusinessErrorManager业务错误管理器。BusinessErrorManager是个简单的service,它通过JMS接收业务异常消息并将消息记录到控制台,以此模仿真实的异常处理应用。

  ExceptionManager接收异常消息并根据异常消息的类型进行某些处理动作。例如如果收到致命异常则会向系统管理员发送邮件;收到标准系统异常则写入本地文件log,例子演示的不是异常处理、演示的是:

  • 所有的service components都是以spring bean的形式在一个mule配置文件当中配置的。
  • error manager拥有多个outbound endpoints出站端点,例子演示了消息如何发布到不同端点。
  • 消息是Java对象形式,并且需要在XML形式之间互相转换。例子演示了链接多个转换器。

 

Running the Example运行实例步骤:

  1. 在命令行下、进入/errorhandler目录
  2. 编辑 conf/email.properties 文件,加入你的SMTP邮件设置,Error Handler将向这个地址发送警告email
  3. 运行 errorhandler 脚本
  4. 新开控制台窗口进入 /errorhandler/test-data/out目录,该目录下还有 3个文件: MuleException.xml、BusinessException.xml、 FatalException.xml.
  5. 把这3个文件一个一个地移到 /errorhandler/test-data/ in目录下, 你可以观察发生了什么,每种异常类型将会触发不同的 endpoint,注意FatalException.xml文件会使Mule向conf/email.properties 中指定的地址发送Email

Summary总结:

  • Mule一启动、ErrorManager 和 BusinessErrorManager 组件就作为Spring beans创建了出来,它们是service component
  • 当一个异常文件拷贝到 errorhandler\test-data\in目录下,该 error handler错误处理器的默认的 inbound endpoint即被调用, target handler目标处理器会对异常进行处理。
  • 当准备好传递消息时,方法返回,Mule调用该service的outbound router出站路由
  • exception manager将消息转换为exception bean,据此决定异常类型。outbound routers出站路由根据异常类型进行过滤。
  • 第一个匹配上消息格式的路由器就被用于路由消息。

  (我将email.properties配置为我的公司邮箱地址,那个smtp.port=25一般不用更改。启动errorhandler.bat,将test-data\out\FatalException.xml拖到test-data\in目录下后即可看到console上有了反应,最后会打印出发送邮件的地址,但是我的邮箱并未实时收到邮件,当停掉console时才收到邮件,似乎邮件不是即刻发送而是当mule停止时关闭钩子会flush一下队列,什么原因暂时不清楚,作为异步消息框架这样似乎是正常的,不过在没有任何负载时应该即刻发送)

 

  2、源码分析:

  在echo例子的源码分析中分析到了Registry注册器 为止了,因为看源码和实践例子最好穿插并行,只看源码崩溃的,光做做例子也无法深入。

  Registry从下到上的继承体系:

  SpringRegistry -> AbstractRegistry抽象类 -> Registry接口 -> org.mule.api.lifecycle.Initialisable+Disposable接口

  我们看到顶层接口属于生命周期包的,Registry注册器 似乎与生命周期管理有关,从上到下分析:

  1) Initialisable生命周期接口声明的方法initialise()在实现服务的初始化阶段 被调用,你可以在该方法实现中加入任何初始化工作;Disposable接口的dispose()方法在实现服务的销毁阶段 被调用。实现者应该在这个生命周期方法中加入释放所有资源的处理(这两个接口方法类似httpservlet的init和destroy,都是由外部容器去掉用,你只要在子类中覆写即可)

  2) Registry注册器 接口包含大量类似spring BeanFactory的方法如:lookupObject(String key)、lookupObjects(Class type)、registerObject(String key, Object value)、unregisterObject(String key)

  3) AbstractRegistry仍然是模版方法的抽象中间层,它把initialise()方法延迟到doInitialise()、dispose()延迟到doDispose()

  4) SpringRegistry具有一个registry_id="org.mule.Registry.Spring",另外它完全是read-only的,不允许注册或解除注册也就是再修改状态。目前看注册器应该是包含spring上下文的且具有唯一id的一种“仓库”。

  参考一段:

  当你需要去存储应用程序能够访问到的运行时数据的时候,你可以将数据作为Object对象存储到Registry中。你可以在任何地方通过访问MuleContext获取Registry对象。

Java代码
  1. muleContext.getRegistry().registerObject(”foo”,”new MyFoo()”);  

 

可以在任何地方使用下面的方法更新对象:

Java代码
  1. Foo foo = (Foo) muleContext.getRegistry().lookupObject("foo");   
  2. foo.setBarVal(25);   
  3. // Replace the previous object   
  4. muleContext.getRegistry().registerObject("foo", foo);  
 

 

三、Loan Broker (基于Enterprise Integration Patterns book 一 EIP书中的例子 ,mule不鸟JBI和SCA,唯遵SEDA 和EIP,有个性)

  0、预备知识及介绍:

  Loan Broker贷款中介(也叫loan agent service)是mule的主要演示例子,顾名思义,就是客户向银行申请贷款的故事。先看一下背景知识:

  以往的贷款请求流程如下图:

  1) 客户customer 向不同的银行bank 发起请求搜寻最优利率。

  2) 每家银行都要向客户询问社保号码ss、贷款数量以及期限。

  3) 每家银行都要对该客户做信用背景调查:通常是咨询征信所credit bureau (通过征信中介credit  agency ),最后银行才能根据这些信息发放贷款。

  4) 客户接收到所有银行的反馈以后,从中选择一家最好的,比如说利率最低。

 

  增加贷款中介以后,这个处理流程可以更加自动化、允许客户在线获取更多银行的实时反馈,耗时要比一家一家询问少得多:

  1) 接收到客户请求以后,loan broker贷款中介从征信所获取该客户的信用信息。

  2) 替该客户向贷方服务lender service 列出的所有银行发出贷款请求(例子中这个服务啥也没做只是个意思)

  3) 将反馈的贷款额度信息打包发送回用户供选择(例子中就是选择返回利率最低的那家银行)

  贷款请求流程如下图:

  这其中的角色包括

  1、贷款中介服务http/rest(接收客户的http贷款请求,包含社保号、贷款额、期限并负责相应放贷信息)。

  2、征信所服务EJB(由贷款中介公司管理的EJB外部服务,做信用检查的,暴露一个名为creditAgency的EJB的getCreaditProfile方法)

  3、征信所网关(例子中的网关做的事情都是:在JMS消息总线和 外部应用或服务/征信所服务应用 之间整理请求)

  4、贷方服务VM(根据客户的资信评分等信息选择请贷的银行,本地pojo组件,决定请求哪几家银行)

  5、贷方网关(在消息总线到贷方服务应用之间整理请求)

  6、银行网关(向多家银行分发贷款请求)

  7、还有几家银行bank(soap协议的消息服务、为了简化、所有银行暴露同样的ws接口。当然你也可以配置不同接口的多家银行)。

  这都算是应用,以往的应用之间通讯是点对点,客户自己去一家一家调用银行服务、所有银行都一遍一遍地调用征信所。而loanBroker就相当于我们的ESB,加入loanBroker以后就不再是点对点而是点对面,ESB就是面、覆盖了征信所、所有银行及各个网关的一个门面(这么看ESB蛮像一个fasade的嘛),这个门面替应用摆平一切,你只要说我要贷款!、其他的如你的资信评级、你都要请求谁、你的请求还需要依赖什么都包办,有事您只管说句话就得。

  例子涉及异步的请求/响应处理模型;对JMS、http/rest、vm、soap、EJB各种协议的调用;把bank暴露为ws。总线中的消息用LoanQuoteRequest 代表,本例中这是个javaBean格式,但是实际中往往是个xml格式(用了ESB,我发现对消息这个东东来说格式是五花八门的:javabean pojo、xml、http参数、stdio、soap甚至json...)

 

  loan broker的示例包含ESB和ESN两种布局的版本,含义参见Mule Topologies的5种拓扑布局:

  ESB、ESN企业服务网、对等网(这不又成了点对点了么,不推荐)、C/S以hub为中心的辐射方式(可能性能有问题,不推荐)、管道方式(服务编排?)

  loan broker示例还包含第三个版本BPM版本,使用了业务处理引擎去编排请求。背景知识基本学完鸟。先看ESB版本:

  1、示例翻译:

  Loan Broker ESB基于当前的Loan Broker示例 但是实现了一个完整的ESB架构,该例子演示了如何使用HTTP/REST、 Web Services、EJB、JMS,他是根据典型ESB实现来配置的。

  Loan Broker ESB使用了JMS消息总线以提供在不同组件和应用间的公共消息通道:

  包含消息端点和组件类型的细节图:

  组件:

  1、Loan Broker Service贷款中介服务 :接收贷款请求(信息包括SS社保号码、贷款额度、期限)并负责收集放贷反馈向客户反馈。

  2、Credit Agency Service征信所服务 :外部服务提供者、它对客户的授信进行检验以确保合理的放贷额度。

  3、Credit Agency Gateway征信所网关 :在消息总线和征信所应用之间整理请求。

  4、Lender Service贷方服务 :基于客户的资信评分,放贷额度和期限,由贷方服务选择请求贷款的银行。

  5、Lender Gateway贷方网关 :从消息总线到贷方应用之间整理请求。

  6、Banking Gateway银行网关 :基于贷方列表、向一家或多家银行分发贷款请求。

 

  总体流程:

  1. 客户应用向LoanBroker 贷款中介服务 发出 CustomerQuoteRequest消息
  2. LoanBroker 贷款中介服务 创建一个 LoanQuoteRequest 消息,这是总线通用消息格式。
  3. Mule通过JMS向Credit Agency Gateway 征信所网关 发送该消息。
  4. 网关整理请求、调用CreditAgency EJB组件,RelectionMessageBuilder自动将CreditProfile附加到 LoanQuoteRequest 消息上
  5. Mule通过JMS向Lender Gateway贷方网关 发送该消息.
  6. 贷方网关 使用VM传输调用贷方服务 .
  7. Mule通过JMS向Banking Gateway银行网关 发送该消息.
  8. Banking Gateway银行网关 通过Axis实现的SOAP调用银行服务.
  9. 每家银行都把自己的贷款报价附加到请求中并通过应答地址ReplyTo 发回LoanBroker 贷款中介服务 。应答地址是由Banking Gateway银行网关 提供的.
  10. LoanBroker 贷款中介服务 的ResponseRouter响应路由接收对应答地址 的响应,它选择最低利率并返回客户。

  2、源码分析:

  从这里改变方式,只看mule源码是不行的,03年mule从sourceforge开始、05年迁至codehaus并发布1.0版本、07年吧出的2.0,现在(2010年)2.2.1源码在6M左右,只看source只会事倍功半。改为以例子的源码分析作为切入点。 这里的分析需要你已经下载mule2.2.1,里面的例子中有loanbroker,结合着它的esb版配置文件(loanbroker\esb\conf\loan-broker-esb-mule-config.xml)分析。网上资料可能大多是mule1.0版本的,这里都是以2.2.1为准。

  本例中,消息总线(JMS、到现在闹不清jms和vm的区别...似乎vm属于jvm内的轻量级队列、jms就是jms范畴的消息队列了)上的通用消息格式是java bean格式。一般情况下如JMS规范要求总线内的通用消息是xml格式,但是mule允许你使用任何数据格式, 我们先来定义这个通用java bean:LoanQuoteRequest 的消息格式(org.mule.example.loanbroker.messages.LoanBrokerQuoteRequest):

Java代码
  1. public class LoanBrokerQuoteRequest implements Serializable   
  2. {   
  3.     /**  
  4.      * Serial version  
  5.      */  
  6.     private static final long serialVersionUID = 46866005259682607L;   
  7.   
  8.     /** The customer request   
  9.      * The request contains Customer info and loan amount and duration */  
  10.     private CustomerQuoteRequest customerRequest;   
  11.   
  12.     /** credit profile for the customer  */  
  13.     private CreditProfile creditProfile;   
  14.   
  15.     /** A list of lenders for this request */  
  16.     private Bank[] lenders;   
  17.   
  18.     /** A loan quote from a bank */  
  19.     private LoanQuote loanQuote;   
  20.        
  21.     //get/set方法......   
  22. }  

  客户的初始请求触发整个事件处理流,客户使用浏览器以htt协议请求mule rest服务,这个服务当然得向外暴露,暴露的方式就是配置贷款中介端点 (CustomerRequestsREST):

Xml代码
  1. <endpoint name="CustomerRequestsREST" address="jetty:rest://localhost:8888/loanbroker" />  

 这么短短一句话的配置含义:

 1、内嵌Jetty servlet引擎

 2、mule启动jetty在8888端口上监听rest请求

 3、把rest servlet绑定到/loanbroker上下文

 来自客户的初始rest请求格式为:

Xml代码
  1. http://localhost:8888/loanbroker/?name=Ross+Mason&ssn=1234loanAmount=10000&loanDuration=24  

 贷款中介端点 以http参数形式接收下来,需要转换为CustomerQuoteRequest对象,所以增加了一个自定义转换器:

Xml代码
  1. <custom-transformer name="RestRequestToCustomerRequest" class="org.mule.example.loanbroker.transformers.RestRequestToCustomerRequest" />  
 

这个转换器要用在贷款中介端点 上,在贷款中介服务的入站inbound配置上、入站端点endpoint引用了贷款中介端点 (CustomerRequestsREST)、同时也引用了这个转换器。也就是说从贷款中介端点 上接收的rest请求都直接用这个转换器予以转换:

Xml代码
  1. <service name="LoanBroker"><!--贷款中介服务-->  
  2.             <description>  
  3.                 The LoanBroker service is our 'entry' service that accepts requests from the outside world   
  4.             </description>  
  5.             <inbound>  
  6.                 <inbound-endpoint ref="CustomerRequestsREST" transformer-refs="RestRequestToCustomerRequest" />  
  7.   ......  

 自定义转换器的写法比较简单请自行参见:org.mule.example.loanbroker.transformers.RestRequestToCustomerRequest,它把rest请求参数封装为CustomerQuoteRequest - CQR,注意CQR是LoanBrokerQuoteRequest的成员,CQR仅仅包含三个最基本的rest请求参数:

Java代码
  1. /** The customer that requested the quote */  
  2.     private Customer customer;//包含用户名和社保号ss   
  3.   
  4.     /** The requested loan Amount */  
  5.     private double loanAmount;//贷款金额   
  6.   
  7.     /** the duration of the loan */  
  8.     private int loanDuration;//贷款期限  
 

  LoanBrokerQuoteRequest除了CQR还有别的成员参见上述LoanQuoteRequest 的消息格式。

  继续、参见上述总体流程中的第二步,贷款中介服务 只做在总线上触发LoanQuoteRequest 这么一件事,mule来处理所有的路由、转换以及对调用者的反馈。 贷款中介服务的配置如下:

Xml代码
  1. <component class="org.mule.example.loanbroker.AsynchronousLoanBroker" />  

  具体代码自行参看,总之贷款中介服务 LoanBrokerService接口定义了一进一出两个方法,分别做消息的请求和反馈:

Java代码
  1. Object getLoanQuote(CustomerQuoteRequest request) throws LoanBrokerException;   
  2. Object receiveQuote(LoanQuote quote);  

 AsynchronousLoanBroker对getLoanQuote方法的实现归结为:

Java代码
  1. LoanBrokerQuoteRequest bqr = new LoanBrokerQuoteRequest();   
  2. bqr.setCustomerRequest(request);  

 就是构造一下LoanQuoteReques 这个通用消息javabean而已。下篇继续loanBroker的分析。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Mule 2.x Getting Started Guide第一部分Mule概述之Mule...
InfoQ: 通过邮件服务器集成应用
Mule Spring Security | Mule Training | Mule ESB, Anypoint Registry, Anypoint Connectors, MMC, APIKit
所谓ESB
几种ESB(企业服务总线)介绍
ESB 企业服务总线
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服