在一个已经使用Weblogic Integration和Workshop开发出多个应用程序的环境中您可能希望考虑一种支持以下功能的方法
组件重用
将多个应用程序共同部署到同一个WebLogic域上
本文关注单个Workshop/Weblogic Integration应用程序——即一个部署单元(一个ear)——的应用程序架构要记住多个应用程序可以部署到单个Weblogic Integration域上所提出的应用程序架构支持
代码的重用维护和扩展
团队工作
根据子元素的可变性在一个应用程序内对项目进行重新组织使其从一个应用程序变为多个应用程
稍后您将看到在一个应用程序内组织Workshop项目将对性能调优造成直接影响
我将分部分介绍
应用程序各层以及将代码织入各层中的方法
在一个简单示例中应用这些方法
对性能调优和部署的影响
第部分应用程序各层以及将代码织入各层中的方法
在定义应用程序构件块时一种好的方法是使用逻辑层这些逻辑层随后可能被扩展为SOA层
对于复杂的应用程序我们通常定义个层如下图所示层与层之间可能包含一个由消息总线(如AquaLogic Service Bus)组成的中介体在本文中我们将不讨论中介体因为我们主要关注的是单个应用程序单个ear中的架构要记住随后该应用程序在开发过程中将被拆分为多个应用程序每个应用程序都被公开为web服务成为一个SOA构件块之后可以使用一个中间层进行服务与服务之间的整合而系统与系统之间的整合基本上使用Weblogic Integration来完成
这些层是SOA相关的它们在单个ear文件中也有意义类似地当在企业范围内应用SOA时在单个应用程序中考虑无疑是提供构件块的最简单的方式
复合层(Composite layer)向企业合作伙伴和外部客户提供对服务的访问提供必要的转换过滤等该层可以聚合来自编排层的业务服务以提供对添加约束过滤和安全性等服务的外部访问该层将用于编排层中的标准XML模型转换为适用于外部业务合作伙伴的简化模型该层向外部客户端公开Web服务该层可能包含作为信息组合的页面流页面流可作为面向业务合作伙伴的Web Interface提供或者使用Weblogic Portal和WSRP将其公开为Web服务
编排层(Orchestration layer)该层包含了Weblogic Integration业务流程业务流程使用标准的XML数据格式该层用于编排许多后端系统在该层中使用标准的模型提供了该层与上下层之间的无关性在对一个后端系统进行更改以针对不同的业务合作伙伴提供适当的服务时这就提供了很大的灵活性和无关性
连通性层(Connectivity layer)该层提供到后端系统的访问它提供从数据的后端表示法到用于编排层中的标准数据格式之间的相互转换
在编排层中使用标准数据模型是一种好方法它提供了应用程序代码与该应用程序所连接的其他系统之间的无关性标准的模型可能由XML模式中所表示的UML域模型组成流程之间这种XML数据的传输应该通过粗粒度消息(定义在UML域模型中由一组对象组成的消息)来完成XML中所表示的与DTO (data transfer object)模式相关的相同理念应该是一个好的起点
使用多个层并不意味着每次都必须通过各个层例如从表示层进入连通性层而不经过编排层的任何组件应该根据对公开于各个层的服务的重用需求对此进行考虑
在每一层中代码和Workshop项目的逻辑编排应该仔细考虑以便提供更多的灵活性
那么如何在一个Workshop应用程序中定义项目呢?
一个Workshop应用程序由多个不同类型的项目组成项目的类型可以是主要包含Weblogic Integration流程的流程项目主要包含java页面流的Web项目用于需要在不同的项目之间共享的控件的控件项目等
那么是否应该每个逻辑层定义一个项目呢?或者是在一个逻辑层中定义多个项目?
我的答案是根据具体条件在每个层上定义多个项目对于Workshop项目以下方法可帮助您做出决策
Bottomup(自底向上)
这是一种由来自后端系统的启动窗体(starting form)组成的方法对于每个后端都应该定义一个或多个Workshop项目随后(第部分对性能调优和部署的影响)我们将介绍定义多个项目的优点这些项目根据需要可以是控件项目或流程项目如果后端将使用一个Weblogic Integration事件生成器调用您的应用程序您可能就要考虑为该后端定义一个流程项目您可能还希望在该层定义应用XQuery转换的流程一个好的实践是不要在连通性层的Workshop项目中使用有状态的流程
然后向上在编排层添加流程以编排不同的后端
Topdown(自顶向下)
企业所需的启动窗体定义了用于表示企业和标准的XML模型的流程该模型随后可被用于编排层您可能希望以UML为起点将域模型实体转换为XML类型将实体组合转换为XML元素(文档)在该层定义将被用作流程的参数的文档时要特别小心
将流程拆分为主流程中的子流程来表示业务只有节点具有业务涵义所有的细节都应该被抽取到子流程如果可以的话应该使用无状态的子流程如果可以的话惟一的有状态流程应该是最顶级的流程从一开始就要考虑对有状态流程进行版本控制
从业务分析的角度将相关的流程聚合到不同的Workshop项目中以每个项目容纳一个技术可重用方面的方式将所有技术可重用的流程放入特定的Workshop项目中
然后向下在连通性层添加控件或流程项目以提供从标准模型到相关的后端模型的转换
Meetinthemiddle(在中间会合)
这是两种方法的结合这种方法很难应用因为它要取决于您对相关系统的了解这种了解不只是业务方面的还包括技术方面的我认为最好是有一个或一组可以将应用的业务方面和技术方面结合起来的架构师您可能希望专注于该应用程序中的一个选定的部分覆盖一个重要的用例并在开发过程中定义第一次迭代
我们来考虑一个典型的例子
两个后端系统一个用于CRM一个用于记帐
两组处理业务逻辑的可重用流程
一组表示业务流程或其一部分的长期活动的流程
一组处理错误的流程这组流程是我们要处理的技术方面之一
如第一部分中所说我们将使用由一个部署单元组成的单个Workshop应用程序作为起点并记得随后可从不同的应用程序重用对后端系统的访问如果在所有的应用程序内部都公开标准的XML模型那么就很容易在不同的应用程序中重用对后端系统的访问在流程之间传递的参数应该从设计角度和技术角度认真考虑后者将在本系列的第部分中进行讨论
取决于后端系统的版本对后端系统的访问可以有不同的生命周期并且可以在开发过程的后期单独进行维护和部署此后应用程序的这些部分可以在不同的Workshop应用程序中重新组织并公开为服务如果这些服务由流程组成那么可以通过webservices控件或流程控件/服务调度程序控件对其进行访问对这些服务的访问应该根据重用需求和重用来源进行考虑在部署在同一个Weblogic域上的应用程序之间如果考虑性能因素那么就可能使用流程控件而不是服务调度程序控件我们将在本系列第部分中介绍性能问题
现在我们回到定义应用程序的项目上我们将从后端系统开始考虑为第一个后端定义两个Workshop项目
[MyApplication][CRMServices]Processes和
[MyApplication][CRMServices]Controls
并为第二个后端定义一个项目
[MyApplication][BillingServices]Controls
注意
包含在方括号[]中的名称是变量
对项目以及包含一组项目的Workshop应用程序的命名应该认真考虑所有项目名称都应该以应用程序名称([MyApplication])为前缀在本系列的第部分我们还将讲到这一方面
在定义项目时我们假设CRM后端需要调用我们的应用程序这通常是通过Weblogic Integration事件生成器实现的这种情况下就必须有一个流程项目可能还需要应用XQuery转换以便将编排层中所使用的标准XML模型转换为后端XML格式或将后端XML模型转换为标准模型在这种情况下可能需要一个流程项目考虑只在流程项目中使用数据转换控制(dtf)
Weblogic Integration事件生成器需要使用一个消息调度程序渠道来发送从后端接收到的消息
对不同后端的访问是在不同的Workshop项目中完成的这是有意为之的在第部分中我们将看到这将对性能调优造成直接的影响我们不希望来自后端的事件引发线程饑饿或可能的死锁
在编排层我们可以考虑定义个项目
[MyApplication][MyModule]Processes
[MyApplication][MyModule]Processes
[MyApplication][MyModule]Processes
[MyApplication]ErrorManagerProcesses
在表示层我们可以考虑定义两个web应用程序其中一个用于与应用程序相关的管理性任务
[MyApplication][MyModule]Web
[MyApplication][MyModule]Web
除了这些项目外我们还可以定义一个用于可重用控制的项目和一个用于java类的项目
[MyApplication][MyCommonModule]Controls
[MyApplication][MyCommonModule]Java
下图描述了所有这些
最佳实践是在开始开发之前画一张应用程序及其不同模块或Workshop项目的图这项任务应该由软件架构师来完成并维护需要考虑与开发重用和性能调优相关的组织需求
图中所使用的图形表示法
注意如图中所示我们可以在流程项目中定义控件和定制控件如果这些控件只由一个应用程序的一个项目使用那么这是很实用的只有用于同一个应用程序或不同应用程序的不同Workshop项目的公共控件需要在控件项目中定义例如流程控件可能被用于从同一个Weblogic域中包含该流程的项目/应用程序之外的另一个项目或应用程序调用流程因此这些控件应该放入一个控件项目以便可以在不同的Workshop项目中重用如果需要在不同的Workshop应用程序中使用这些控件可以考虑将其放入一个公共目录中并通过引用或作为库将控件项目导入到不同的应用程序控件项目将在应用程序的APPINF/lib目录下生成一个jar文件
第部分对性能调优和部署的影响
性能调优
根据层选择多个项目之后正如本blog第部分所述业务模块或后端将为应用程序性能调优提供更多机会如果来自后端的事件很多为了防止默认队列中的所有线程都用于处理这些事件出现线程饑饿的情况这就相当有用对于Files Event Generators我们肯定能够使用针对文件事件生成器中的轮询文件的读取限制进行一些调整但是这可能还不够因此为属于同一项目的所有流程指派一个专用的线程队列可能是一种更好的方法
对于异步调用的流程或者对于具有缓沖方法调用的控件AsyncDispatcher队列将用于调用一个Message Driven Bean而这个Message Driven Bean将使用在Workshop项目的WEBINF/wlwconfigxml文件中指定的执行队列这种设置将在底层EJB的DD中生成正确的指派元素
<wlwconfig xmlns=><asyncdispatchpolicy>applicationprojectExecuteQueueName</asyncdispatchpolicy></wlwconfig>
对于同步调用例如由一个外部http Web Service调用启动的同步调用需要在WEBINF/webxml中指定线程队列
应该使用Weblogic Server管理控制台创建相关的执行队列如果这些队列不存在于服务器上那么将使用默认的队列
可以在wlwconfigxml Configuration File中找到更多信息
要了解Workshop的内在本质可以参考这篇文章l
项目和应用程序命名
在一个Weblogic域中Workshop项目名称必须是独一无二的一个Weblogic域可以作为组成Workshop项目的许多Workshop应用程序的宿主为了避免上下文沖突使用应用程序名称作为所有项目的前缀是一个不错的选择
[WorkshopProjectName] = [ApplicationName][ModuleName]
使用Web Service Control或Service Broker Control来访问项目上下文或流程是通过使用(默认)包含项目名称的URL来实现的例如我们将会有
//server:port/[WorkshopProjectName]/com/mycompany/mymodule//ClientOrderjpd
Workshop项目内部使用的JMS队列也是从Workshop项目名称导出的一个叫做WorkshopProjectName 的项目将需要两个队列
[WorkshopProjectName]ProcessesqueueAsyncDispatcher
[WorkshopProjectName]ProcessesqueueAsyncDispatcher_erreur
从开始就考虑控制有状态流程的版本
在 Versioning JPD On Running Instances中可以找到有用的相关支持模式
调用流程及相关考虑
当在同一个域中从一个流程调用另一个流程时根据设计抉择可以选择使用Process Control或Message Broker如果它们位于同一个Weblogic Integration域中这将对不同项目或不同应用程序中的流程有效从另一个Weblogic域调用流程可以使用Service Broker ControlWeb Service Control或JpdProxy来完成后者可以在任意java客户端中使用
可以把Process Controls 复制到 ControlsProject从而在不同项目或不同应用程序中的流程之间共享它们
使用Process Control时如果子流程是同步的它将与调用者在同一个线程中执行在同一个Weblogic Integration域中使用Service Broker Control而不是Process Control这将使用在被调用的流程一方的另一个线程因为它将通过基于HTTP的 SOAP协议被调用这对于性能来说不是最优的
借助复杂的Java类型跨应用程序边界使用Process Control进行同步调用时需要进行特殊的考虑应该把java类添加到应用服务器的系统classpath中以避免classcast异常有关classcast异常的信息请参考#文档
注意在jpd中创建的XmlBeans文档是以特殊方式进行处理的这由XmlBean的Factory完成而它将根据其执行的上下文来创建bean当在流程的上下文中调用XmlBean的Factory时它将创建一个类型为combeawlivariablesProcessXML的代理对象允许在应用服务器系统classpath中没有XmlObjects类的情况下借助XmlObjects跨应用程序边界使用Process Control进行同步调用