备忘录

记录学习过、研究过、使用过和总结过的内容,以备不时之需

统计

留言簿(4)

积分与排名

其它

技术网站

牛人博客

阅读排行榜

评论排行榜

Mule介绍(转)

Mule是一个企业服务总线(ESB)消息框架.它的主要特性包括:
1.基于J2EE1.4的企业消息总线(ESB)和消息代理(broker).
2.可插入的连接性:比如Jms,jdbc,tcp,udp,multicast,http,servlet,smtp,pop3, file,xmpp等.
3.支持任何传输之上的异步,同步和请求响应事件处理机制.
4.支持Axis或者Glue的Web Service.
5.灵活的部署结构[Topologies]包括Client/Server, P2P, ESB 和Enterprise Service Network.
6.与Spring 框架集成:可用作ESB 容器,也可以很容易的嵌入到Spring应用中.
7.使用基于SEDA处理模型的高度可伸缩的企业服务器.
8.强大的基于EIP模式的事件路由机制等.
Mule发布最新版本1.1,这个发布包括集成了JBI,对 BPEL的支持,还增加一些新的传输器(transport)Quartz,FTP,RMI与EJB等。

一、总述  

      Mule的运作能力也许是它在开源ESB中最大的优势:商业的支持公司Mulesource.com,给大家贡献代码的MuleForge.org,年度大会MuleConf,还挖来了CXF的作者与SaleForces的CXO......

二、示例

三、Mule的功能

1.  重温ESB的功能

  • 解耦中介:客户对实际服务提供者的身份、物理位置、传输协议和接口定义都是不知道也不关心的,交互集成代码提取到了业务逻辑之外,由ESB平台进行中央的宣告式定义。
                  ESB平台实现协议转换(WebService,Http,JMS...),消息转换(转换、充实、过滤),消息路由(同步/异步、发布/订阅、基于内容路由、分支与聚合...)。 
  • 服务中介:ESB平台作为中介提供服务交互中的基础服务。
                  ESB平台实现SLA(可靠性保证,负载均衡,流量控制,缓存,事务控制,加密传输),服务管理监控(异常处理,服务调用及消息数据记录,系统及服务的状态监控,ESB配置管理),统一安全管理(这个有点理想主义)
  • 服务编排:多个服务进行编排形成新的服务。
                  ESB支持一个直观的形式定义新组合服务的流程(工作流、BPEL 或 代码级编排)。

2. Mule的解耦中介

    Pluggable的传输层,路由器,转换器是所有ESB必然支持的核心功能,作为《Enterprise Intergration Patterns》的遵循者提供如下:

  • Transport:WebService、JMS等常用的协议都已满足,IBM MQ在企业版中提供,只缺Weblogic Tuxedo了。
  • Router/Filter:提供EIP中描述的路由
    1.基于内容路由,Fillter提供消息类型、消息属性、JXPath和OGNL表达式的基础过滤能力。另有去除重复消息的Router。
    2.接收表基类,由用户自行实现。
    3.分拆聚合重排路由。
    4.流程编排路由见后。
  • Transformer:提供基础层次上的的协议类型转换、XML<->Java转换、编码、压缩、加密转换。业务级转换由用户实现。

      不过,1.4版中的Transport的实现质量很一般,而Router、Filter、Transformer都实现得较简单和基础,

      最后,Mule额外提供了POJO的编程模型,而不是痛苦的XQuery Base的XML消息。

3. Mule的服务中介

     提供较基本的中介服务:

    其他的能力如流量控制、负载均衡,可基于Mule的机制自行实现。

4. 服务编排

  • ChainRouter简单实现Pipeline模式
  • JBPM Router(见loanbroker example)。
  • 在1.4版中还有OSWorkflow Router  和Apache PXE BPEL Router。

5. Service Container

   这是个额外的Bonus。Mule的身份并不纯粹。如果Component是什么都不干的Bridge Component,它就是真正纯调度外部服务的ESB。
   如果Component是业务POJO,在Mule中运行业务逻辑,Mule就成为一个Service Container,类似于SCA Domain。
   这时候它本身就是Spring+CXF的,额外有多通信协议支持,有SEDA(Staged Event-Driven Architecture),有异步编程模式,有服务中介基础设施,作为后台服务容器也是个不错的选择。
   日后自己可能会越来越多使用Mule 2.0+Terracotta作为自己的服务容器方案。

四、Mule2.0 印象

    与Mule 2.0抵死缠绵了两周,喜忧掺半。但只在2.0之后,Mule才算真正站到了ESB的起跑线上。

1. 很Spring,很SCA的配置文件

  • 全Spring又全nameSpace化的配置文件,简洁而规范,在IDE中有良好的提示。
    尤其是transport相关的endpoint的改进明显,原来的URI<endpoint address="pop3://bob:secret@localhost:62002"> 或如下的connector
<connector name="SystemStreamConnector" className="org.mule.providers.stream.SystemStreamConnector">
<properties>
<property name="promptMessage" value="Please enter something: "/>
<property name="messageDelayTime" value="1000"/>
</properties>
</connector>

            改为transport特定的namespace后,IDE中清晰显示了可选的配置项。

<stdio:connector name="SystemStreamConnector" promptMessage="Please enter something: "messageDelayTime="1000"/>
  • SCA的Service/Component概念。
    Service/Component代替了原来注定要被遗忘的MuleDescriptor,其中Component定义业务逻辑的POJO,Service定义如何以服务的方式管理组件的配置。
    在POJO中调用远程服务的Nested Router也改为了很SCA的Binding。
    Component也有Component 与 PooledComponent的选项。完整的例子如下:
<pooled-component>
<spring-object bean="mySpringPojo"/>
<binding interface="org.mule.example.loanbroker.credit.CreditAgencyService">
<outbound-endpoint ref="CreditAgency"/>
</binding>
<pooling-profile exhaustedAction="WHEN_EXHAUSTED_FAIL" initialisationPolicy="INITIALISE_ALL"
      maxActive="1" maxIdle="2"maxWait="3"/>
</pooled-component>

      上文按pooling-profile定义的pooled-component,在spring中定义mySpringPojo,并将一个远程的CXF Endpoint binding到POJO的CreditAgencyService变量中,可直接调用;

  • 可视化拖拽的Eclipse 插件Mule IDE。
    虽然还非常原始,但总算有个盼头。

2. 架构的更改

  1. Web Service支持增强
    随着CXF作者的加入,Web Service这事实上SOA里最重要的Transport得到了加强,WSDL终于可以通过annotation准确配置。
    虽然无奈,就冲这个理由就应该升级到2.0了。不是2.0太好,而是1.4太差了。 
  2. REST支持增强
    Mule RESTPack,支持apache abdera(Atom Publish协议实现),Jersey(JSR131 RESTful WebService实现)和Restlet 三种Transport。
  3. 代码结构的合理化
    抽象出相对稳定的org.mule.api接口包,代替原来的org.mule.umo包。
    开发团队还检查调整了Mule中所有对象的定义,使其更加准确。
  4. 各个模块的升级
    如核心MuleManager大对象拆成MuleContext and Registry,运行时Reistry支持动态加载Service,支持向OSGI进军;
    如以流的方式转换处理消息。
    如SEDA模型定义的细化,见后。
  5. 工具增强
    Mule Galaxy SOA治理工具(开源), Mule Saturn 消息流监控工具,Mule HQ 底层监控工具。
    不过还没试用不知道实际效果如何。

3. 遗憾的地方:

  1. 性能下降
    无论是代替XFire的CXF还是Mule 2.0,都拖得性能大大下降。(但用JDK6的话情况又好一点)
  2. 仍然没有自带的集群,负载均衡,流量控制实现。
    不像BEA、ServiceMix都使用JMS的底层,Mule使用vm queue在单一JVM的节点间流动。
    我们团队主要用TerraCotta在集群里同步状态数据,流量控制与负载均衡也是自己实现。
  3. CXF transport 仍然使用Mule自己实现的Http Connector。
    CXF Standlone也是用Jetty的,看tomcat们努力的劲头,相信谁都能随便实现一个不错的Http Connector。
  4. 从1.4升到2.0非常的花时间。
    估计团队重构的太兴奋了,从代码到配置文件再到XFire to CXF,一些代码级修改还没文档详述。
  5. 文档从1.4版更新到2.0版的进度太慢,而且文档仍然简略。
  6. 质量仍然在使用中检验。
    文档说2.0版本的比1.x版本增加了30%的单元测试用例,按理来说项目质量应该提高了。
    但还是被我发现了在很重要的AbstractEntryPointResolver类里,居然有内存泄漏。(http://mule.mulesource.org/jira/browse/MULE-3521)
    原因是用了StringBuffer作为HashMap的key,而SB并没有重载Object的equals()函数的,结果map永远都在增大。

这说明了,开源项目的质量,最终是靠一个积极使用和反馈的用户群和一个活跃的开发团队,"用"出来的。

五、诡异的消息流

     不同的inbound-outbound模式下,Mule中的消息流与交互模式非常诡异,不熟悉的人会很痛苦,详见交互编程模式

  • 同步模式:如果component有outbound,最终向调用者的返回结果就是outbound的返回结果而不是component的。
                    当不再有outbound后,如果component的函数返回null,则返回NullPayload,如果函数为void,返回请求参数,其余正常返回。
  • 异步请求应答模式:一个同步Inbound,一个Ountbound(通常有reply-to的配置),一个 async-reply。Component请求,发给outbound,在async等待outbound返回,再返回给调用者。

六、诡异的SEDA模型

   Mule 2.0的SEDA模型配置更加细腻,但却没有文档描述,以下都是从配置文件的Schema读出。

  SEDA的配置项仍然分Thread Pool、Component Pool、Queue三项,但其中Thread Pool又细分Receiver,Dispatcher ,Component 三项。

  • <configuration>可设定全局的Thread Pool,又分default-threading-profile与default-receiver-threading-profile等四项。后面三项如果没有特别设定,则采用第一项的值。
  • <connector>可设自己的dispatcher与receiver threading profile。
  • <model>可设自己的queue profile。
  • <service>可设自己的component-threading-profile与queue profile
  • <pooled-component>可设自己的pooling-profile。

换个角度描述:

  • Threading:<configuration>描述全局默认Threading,<connector>描述dispatcher与receiver,service描述compent-threading
  • Compoent Pool:<pooled-component>
  • Queue:<model>,<service>

最后结果,配了default-threading-profile为100后,系统开了100条的http.receiver,其他component和vm.receiver都只有1条线程。在典型场景的CXF -> component->同步VM Queue ->component的情况下,一个请求的两个component都在同一个http.receiver线程内执行。

相对于1.4的改进:

  Thread Pool的配置细腻了,而且不会去开N条实际用不到的vm.receiver

  Component 不再默认有个对象池,也可以是<component>指向自身或Spring的单例,<pool-component>时才做池化处理。

posted on 2008-09-09 17:03 雪山飞狐 阅读(1603) 评论(0)  编辑  收藏 所属分类: 开源框架


只有注册用户登录后才能发表评论。


网站导航: