本单包含内容如下:
最好不要把业务逻辑放在Map中,Maps只适合用来处理不同格式间的转换。
业务逻辑放在Map中的一个好处是,你可以通过生成一个新的GAC assembly,然后重启宿主实例就可以更新BizTalk应用,以至于减少因为因为打补丁需要的停机时间。当然这也不是一个把业务逻辑放在MAPS中的好理由。
在Orchestrations中放置太多的业务逻辑也不是推荐的方式。
Orchestrations关注的是消息处理,工具箱中的loop和判断组件如同编程语言中的一样,在同一个Orchestrations中放放置大量业务逻辑就如同在C#中在一个方法中放置大量代码,不易于开发、设计和维护。
Orchestrations并不是Biztalk的开发语言,不能像编译语言一样对待。
由于Business rules独立于BizTalk应用解决方案,所以它们在更新或者修改的时候不需要对整个解决方案进行修改。也就是不需要再编译程序。
BRE是一个理想的地方来处理逻辑,比如路由和业务判断
几乎任何.Net组件都可以在自定义管道组件中被调用,比如BAM和BRE。
ESB Tookit 也是通过管道实现的。
管理的参数可以在BizTAlk管理控制台中设置。
容易理解,减少内外间的依赖。
开发这东西和WF是同一个团队的人,所以有很多相似的地方,但是有一个最大的区别,那就是消息在biztalk中是不可以被改变的。
这两个都有同一个概念:
脱水(dehydration):保存状态,工作流可以从内存中移除。在Orchestration中我们无法直接控制dehydration发生。
Orchestrations被编译成X#,与C#相似,但是不同。
Orchestrations的引擎叫XLANGs
Orchestrations的使用成本相当高。比如在消息数据库中消息的读取和写入。尽量避免使用orchestration.
下图中的情况就不应该是Orchestrations应该解决的问题:
上述这个情况直接可能通过过滤器来实现。
同样的结果,多种实现方式,我们可以看看在运行中时它们包括的步骤,这里先提一个概念“Message box hops”,它是处理经过Message box的环节。这个环节的开销是昂贵的,应该尽量避免。
在上图利用Orchestrations的解决方案中,运行时的执行步骤如下:
每一步都需要与message box做交互,再来看不使用Orchestrations的解决方案:
很明显,第二种方式的消息行程相当于第一种方式的一半,性能当然也会优于第一种两倍。
另外:biztalk是一个平台,在同一组中,性能低的应用程序会影响到其它应用程序。
是不是多部分消息,看是不是有多个body.
在Orchestrations中使用多部分消息的好处是隔离架构变化对Orchestrations的影响。
多部分消息类型给了我们另外一个间接的层面,也是一种可利用的类型。
给一个消息指定架构时就像指定一个类型,它实际上会在Orchestrations中创建一段话,声明变量和类型:
OrderSchema MyMessage
任何使用这个消息的地方,Orchestrations都必需要写上这行代码。这表明,当然们改变一个非多部分消息时,需要在Orchestrations设计时断开所有的端口、发送和接收组件(形状)。
要改变这种情况,就是使用多部分消息类型,然后在多部分消息中创建一个body绑定为我们要的架构。然后就可以使用多部分消息。这个实际上会被转变成一段声明,类似于:
IMySchema MyMessage
这不是一个准确的转换,因为Orchestrations实际上不关心之前的接口是什么,反正它就在这里。这有点类似于COM。
多部分消息可以在Orchestrations中被重用,所以我们不用创建很多消息类型。这个增加了一些耦合度。
通过创建一个空的Orchestrations只用于定义多部分消息和共享类型也是一个非常好的方法。
这和OOP编程中的建议一样,避免使用过长的方法体。
可以通过”Call Orchestration“工具对Orchestrations进行划分。这东西类似于call 的方法,是同步的。可以传递和获取参数,包括外用参数。
发送形状是比较常见的引用脱水的点。
可能使用性能计数器来测定脱水点。
减少脱水点的方法 包括:
流程允许我们创建.net类型变更 ,在业务处理中使用.net类的方法。这是一个伟大的功能,但是任何被使用的类在Orchestrations中作为一个变更,必需被标记上可序列化的属性。这就允许Orchestrations引擎在运行流程中存储这个类,也就是持久化。
对于已经存在的没有可序列化属性的类,我们可以使用atomic scope来调用。
atomic scope遵循ACID原则,要么全部成功,要么全部失败。这也就是为什么不能在一个atomic scope中既放send又放receive,因为message box是一个不能被锁定的资源。
不要使用atomic scope简单地调用不能序列化的.net类的方法。 如果必需要调用一个不可序列化的类,而且只能在atomic scope中调用,那么把这个与其它操作整合,比如下面:
最佳的方式来解决这个问题是创建一个封装类。
Orchestration引擎允许我们把消息置为XmlDocument类型,但是这不意味着我们可以这么用。
XLANGs中的XmlDocument实际上是一种特殊的XmlDocument封装类。这是不可以被序列化的。
XmlDocument加载内容为DOM,DOM允许随机访问内容,所以会把整合内容加载到时内存。它会占用相当巨大的内存以便快速访问,通常100K的消息会占用到1M的内存。这很容易引发内存压力和吞吐量。
XmlDocument可能通过它的成员修改其内容。虽然消息在Biztalk中是不可以被修改的,但是XmlDocument可以在本地被修改而不反射到message box中。
对于在Orchestration传输一个非XML消息,可以使用XLANGMessage.这个类可以使用指明该消息是非XML消息,并且不需要被处理。而且战用内存小。跟XmlDocument一样,XLANGMessage也可以被指定要任意消息。
XLANGMessage类可以在这里找到:
Microsoft.XLANGs.BaseTypes.dll 下的
Microsoft.XLANGs.BaseTypes 命名空间
另外,可以通过xsd.exe来 创建.Net类来匹配架构,它会根据消息架构来生成类。
主要由于大消息的原因。
Content Based Routing(CBR)
我们可以在Orchestration的判断工具进行基于内容的路由选择,如下图:
但是这不是一个最优的解决方法 ,因为这个已经被硬编码了。可以通过CBR也解决这个问题,也就是Orchestration中的 direct bound Port,要实现上述场景,只需要三步:
X#语言提供给我们一些特别的工具,让处理消息更容易。其中一个就是xpath函数,这可以设置或者恢复XML消息中的值 ,语法如下:
xpath(Message/Part,<<XPath expression string>>)
通常这样的操作需要很长的一个语句,比如:
比较好的方式是使用distinguished字段:
之后就可以直接使用:
当然使用distinguished Fields也有缺点,比如,这们必需在消息的运行中时确实存在。
上图就是一个不好的使用方式,因为它使用xpath和DOM来创建不同的消息。然后,每个子消息被发送,这就引发一个脱水点。
如果要分解这个消息,最好通过调用一个XML disassembler的pipeline来处理。
有两种好的解决方式:
pipelines可被认为是最小的biztalk服务器组件,是处理消息流的装置,被实现为管道 和过滤器的设计模式。在这个模式下,处理组件被旋转成为一个链。
两个非常重要的活动在pipelines中发生,即 1.消息的转换,2.属性升级。
上图就是一个空的接收管道,这个是一个PassThruReceive 管道。
上述4个场景(stage)每个都可以包括0-255个组件。除了“Disassemble”,四个场景的描述如下:
Stream Processing用来把大消息分解成为足够小的消息,减少内存占用。
Pipeline是基于流的。