biztalk 2010 架构
架构
架构描述在biztalk和不同系统之间传递的消息的结构。当然,这种也被称为协定的架构必不可少的,因为没有协定传递的消息就不能进行验证,这将会导致一个不一致的、无法预测的系统。如果biztalk无法确定输入的有效性,那么他也无法保证输出的有效性。很明显这不是我们所期望的。当双方协商确定了架构以后,你就可以轻松的解决失败消息和确定发送者是否发送了无效的消息或者接受者拒绝了一个有效的消息。同时,一个详细的、准确的协定允许你拒绝无效的传入消息,让开发者可以确定biztalk解决方案的所有其他部分的输入的有效性。
基于架构,biztalk会产生一个消息类型。这个消息类型在订阅中使用,它对MessageBox决定哪个编排和发送端口应该接收发布的消息很重要。例如,没有消息类型,就不可能有任何一个编排可以接收和处理订单的消息,因为无法确定哪个消息是订单的消息。
映射使用架构定义输入和输出的结构。映射的输出时可扩展样式表语言转换(XSLT),它是基于源消息和目的消息的架构生成的。为了保证映射尽可能的简单,你所依赖的输入的结构是至关重要的。
由于在biztalk的解决方案中架构是如此的重要,我们不应该被轻视。花费时间确保架构的尽可能的正确和详细是值得的。如果你不花费充足的时间在架构上,在校验输入和处理无效输入的时候面临困难。
如果你需要同时部署同一个架构的多个版本,你需要给架构定义版本,这可能很麻烦。开始的时候最好在架构上下足够的功夫,减少后来由于架构错误导致为架构定义不同的版本。当然更改可能发生在以后的任何情况下,比如业务需求改变了。在这种场景中,版本化或许是需要的。
Biztalk使用xml模式定义(xsd)来描述进出biztalk的消息。
内部架构
当开发一个集成不同系统的biztalk解决方案的时候,你或许会考虑开发一种内部的架构格式,它可以在biztalk内部使用而不是使用不同的集成的系统的数据格式直接映射。为了理解为什么这样做,我们可以考虑下面这个场景,当一个客户给你发送了订单,你需要将订单与客户订单确认书、经理审核表单、ERP订单进行映射。可能还会有其他的系统需要从这个订单映射某些消息。
如果客户想更改自己的订单格式,你必须修改这个订单的架构和其他三个映射。如果你使用内部的订单架构与客户订单进行映射,同时使用它作为基点与其他三个进行映射,现在你将只需要修改订单架构和其余内部架构的映射文件。
如果包含一个业务处理过程,情况会变得更加糟糕,因为如果你没有将来自不同客户的订单与内部的格式进行映射,那么一个编排需要定义很多格式来识别和处理订单。因此,最佳的实践就是总是维护一个在biztalk内部和你的业务处理过程中使用的内部架构集合。这样可以有效的解除你的业务处理过程跟贸易合作伙伴、内部系统使用的特定格式的耦合。
XML架构
正如前边所讲的,biztalk使用XSDs来描述接受和发送的消息。biztalk使用XSDs来描述XML文档、平面文件和其他的格式。使用visual studio 2010我们可以新增已经存在的架构,使用已存的DTD(Document Type Definition)、XDR(XML Data Reduced)、格式良好的xml文档生成架构,也可以手动创建生成自己的架构。
平面文件架构
biztalk使用XSDs描述平面文件和XML文档。乍一看,这可能让人感到奇怪,因为XSDs是专门描述XML的。这是通过将平面文件所特有的信息保存在架构的注释中,包括分隔符、字段的长度等。架构中的记录描述了一个平面文件,它的字段是由点号区分的,如图7
图-7 平面文件架构
visual studio提供了手动和利用向导创建平面文件架构的方式。跟平常的架构文件一样,没有两个架构的目标命名空间和根节点的组合是相同。这一点并不能立即想明白,因为平面文件没有根节点和目标命名空间。之所以它还如此重要的原因是平面文件会被平面文件分解器转化成XML并且消息类型会被用作路由、选择正确的映射等等。这使关注平面文件的消息类型跟XML一样重要。
EDI(电子数据交换)架构
对于EDI,biztalk提供了8000多种开箱即用的架构供你在EDI解决方案里使用。由于如此多的架构文件,它们被压缩了而不能够直接使用。如果要获得这些架构,需要在安装目录下的XSD_Schemas\EDI文件夹下执行MicrosoftEdiXSDTemplates.exe。如果你不改变解压到的文件就会解压到当前文件夹下。你可以简单的将需要使用的架构添加到项目中。
在添加之前,考虑一下你有哪些贸易伙伴、它们使用的是什么架构。你将会发现很多公司没有使用标准的架构,而是为了适应特定的业务需求的修改版本。架构添加到项目中以后,你可以自由的修改架构,但是需要谨记的是不能同时部署两个具有首节点和目标命名空间组合的架构。更重要的是,EDI架构也严重的依赖注释。所以,修改这些架构要十分小心,并且需要了解EDI文档定义和实现的指导规范的人来操作。
不是XML和平面文件的消息
biztalk对XML、EDI、平面文件提供了友好和丰富的特性支持。然而,有时你需要接受biztalk不支持的文档类型,比如Excel、PDF、Word、image等等,为了支持这些类型,你会有几种选择。
管道传输
作为通用的规则,当一个消息到达biztalk,biztalk在接收管道将消息转化为XML。这个过程需要对传入的消息做一些智能处理,比如查找消息中的值、转化消息、基于消息类型路由等。
如果你不需要这些处理过程,仅仅需要保持进入消息的原始状态,你可以使用PassThruReceive管道。这个管道不会试图解析和理解接收的消息。它仅仅是将消息传递到MessageBox,然后你需要基于有限的知识(文件名、时间戳等)来路由。
自定义拆分器
biztalk中负责将接收的格式转化为XML的组件是位于管道中的拆分器组件。理论上来说,任何管道组件在管道到的任何阶段都可以对消息进行任何的操作,但是做这件事最合适的地方是在管道的拆分器中。如果没有可用的拆分器,那么我们就需要开发自己的拆分器。
自定义编辑器扩展
如前所述,编辑器扩展使你可以描述那些在记录、元素、属性中可用的特定属性。所以如果你想开发一个通用组件用来解析特定格式的文档,或者你想开发biztalk加速器来销售,你可以考虑开发自己的架构编辑器扩展。
第三方组件
有时开发自己的架构和拆分器来解析消息会消耗你很长的时间,购买组件、适配器或者加速器反而更加经济高效。市场上有很多的组件可以帮助你解决特定类型的消息,比如Excel、PDF、Workd、图片等。
属性升级
我们有充足的理由证明,你在业务处理的不同阶段需要方位消息中的字段的值,理由如下:
基于内容路由:你常常需要基于消息的内容路由传入的消息,比如订单总额、供货商id等等。
基于内容计算业务规则:你常常需要基于消息的内容作出决策。
biztalk中的属性升级通常是从传入的消息中取出值,然后将其移入到消息上下文中,方便路由的时候访问和使用。消息上下文是关于消息的元数据的集合,连同消息一起保存在MessageBox里,其允许biztalk的不同部分只读取元数据的一小部分,而不是整个的消息,这样运行时就可以防止直接从消息中访问值。在编排内部,要想获取消息的值,你只有三种选择:可分辨字段、升级属性、直接使用XPath。
并不是所有的消息内容都可以作为可分辨字段和升级属性。只有在消息中仅仅出现一次的字段才可以升级到上下文中作为可分辨字段或者升级属性。如果你试图升级一个在消息中出现多次的元素,将会抛出错误提示。
有时候这中限制看起来是没有必要的,但是当你仔细思考后就会明白了。如果一个元素出现了多次,负责升级的拆分器就无法确定选择哪一个升级。虽然这是合乎常理的,有时你确定给定的元素只会出现一次,但是却在架构里允许出现多次。在这种情况下,你或许会想hack一下,比如游动编辑XSD文件添加这个只出现一次的元素的XPath。然而这样并不奏效,因为编译器将会抛出错误。一种可以实现的方式是使用自定义管道组件,让它计算XPath表达式和升级属性。
可分辨字段
可分辨字段是来自消息并且被标记为可以区别的字段。可分辨字段可以通过编排的点标记使用,并且可以用来获取和设置特定字段的值。这个升级属性石不同的,是不会写入到MessageBox的订阅表的。当消息到达的时候,biztalk知道将什么内容放进到上下文中,这些信息其实是存储在架构里德。当消息到达的时候,拆分器会查找架构并确定所有定义的相关属性拷贝到上下文中。可分辨字段的主要优势就是可以以一种快速、方便、直接的方式访问消息中的值。
升级属性
可分辨字段是一种卓越而快速的访问和写入值的方式。然而有时你需要标记消息的内容来进行路由。这就是升级属性的作用。可分辨字段包括消息的内容并将其放入消息上下文,然而升级属性可以是放入消息上下文的内容,也可以使元数据、常量和其他可以放入消息上下文的东西。可分辨字段和升级属性都可以在编排中访问,但是只有包含关联关系的升级属性可以用来路由。这是因为只有升级属性被写入MessageBox的订阅表中,路由策略使用这些决定哪个订阅者应该获得这个消息。
升级属性的升级过程跟可分辨字段的处理过程基本是一样的。这就是说两者进行升级的场景时机是一样的。主要的不同点是可分辨字段仅仅将字段进行标记,升级属性需要使用属性架构中的属性。属性架构在很多方面跟普通架构是一样的,但是有如下的不同点:
只允许使用元素。
只允许顶级元素,所以都没有子。
使用Schema元素的DocumentType属性标记架构为属性架构。
引入属性架构的原因如下:
biztalk需要知道设计时的时候有什么可用属性,因为你可能想在编排中使用这些属性进行路由。 在部署的时候,当你指定发送端口的过滤器的时候,管理员控制台会列出在部署的属性架构里发现的 属性。
当部署的时候,这些属性将会进入MessageBox数据库以便使其可以知道使用那些属性对发布的消息 和已存的订阅进行匹配。
升级属性实际上以两种形式出现。有一些是提升到上下文中,而有一些是写到上下文中。可分辨字段也是写入到上下文中;与写入型升级属性不同,可分辨字段映射的是消息本身的特定字段。写入到上下文的升级属性仍然是上下文。biztalk运行时在上下文中有很多的可写入属性,它们很有用,因为它们是关于消息的元数据,它们可以被编排和自定义管道组件访问。由于它们不是升级的属性,所以不能基于它们进行路由。
属性降级
属性降级是属性升级的相反过程。它从消息上下文中获取值并写入到消息上下文中。就像拆分器控制属性升级,属性降级也是由拆分器完成的。拆分器降级属性需要三个先决条件:
内置的拆分器组件支持元素的降级,不支持属性。
就像属性升级,你需要建立两个属性间的引用,以使拆分器知道升级属性从哪里获取值,知道将值写 入那个元素。
你需要在输出的消息中创建空的元素,以便拆分器将值写入。如果待写入的元素没有出现在消息中, 拆分器将不会进行降级,也不会重写已存在的值。
存在如下的两种例外的情况:
编排可以独自完成它们的降级。这允许属性降级,并且会覆盖已经存在的值。
通过XML拆分器进行降级的时候,如果没有消息类型出现在文档中,元素中已存在的值将会被覆盖。
属性降级经常被用来确保来自信封的值可以写回到输出的消息中。
可分辨字段和升级属性的优缺点
可分辨字段的优点
1.可分辨字段在编排中可以使用点标记样式访问,其对开发人员是可见的。
2.升级属性需要属性架构,可分辨字段不需要。
3.每次消息发送的时候,MessageBox会进行大量的join。消息上下文、可能的属性、所有订阅的属
性都会进行join。这意味着应该尽可能减少升级属性。所有在属性架构中不要定义任何不使用的属
性。
4. 只有可分辨字段可以将值写入消息的内容中。改变升级属性的值仅仅改变上下文中的值。降级可 以帮助你将值写入内容中,但是可分辨字段更容易实现。
升级属性的优点
1. 只有升级属性可以用来路由。
2. 因为关联是一种特定形式的路由,这也需要升级属性。
3. 可分辨字段包含的是来自消息中某元素的值,升级属性包含的是消息的元数据。
4. 内置的跟踪功能只可以跟踪升级属性。
尽管它不影响可分辨字段和升级属性,基于XPath表达式可以用来从消息获取值或者设置消息中的值。这听起来很强大,但是可分辨字段和升级属性都在消息上下文中,因此检索速度会比较快,而xpath函数需要编排引擎将整个消息加载到内存中来计算XPath表达式。所以xpath函数会更慢,我们只应该在为可分辨字段和升级属性无法使用的循环元素获取和设置值时使用它。同时硬编码一个xpath表达式在编排里边,在架构改变后,往往会发生错误,需要你手动更改。
架构的版本控制
如前所述,很多的东西都需要依赖架构,比如转换、消息类型等。架构的版本控制如此的重要,因为有很多的东西都依赖它。
同样如前所述,同时部署两个架构它们将会共享同一个根节点和目标命名空间的组合,这种做法并不推荐,而且大多的时候会给你带来麻烦。在某些情况下,当更新架构的时候将会是一个挑战。
如果一个架构改变了并且运行时已存的管道、映射和编排需要旧的版本,但是你又不想将架构版本化,这样你就不能部署那些依赖包含你更新的架构的程序集的程序集。否则,你必须版本化你的架构。
两种场景下需要考虑部署架构的新版本,如下所述:
非长事务和可接受短时间停机
如果你没有任何的长事务并且可以接受短时间的停机部署,这是目前为止最容易的解决方案。你可以按照如下步骤操作:
1. 根据需要更新架构。
2. 更新需要使用新更新的架构的映射。
3. 重新编译使用该架构的项目和任何依赖该项目的项目。
4. 导出绑定,每次一个,无论是对于整个应用程序还是对于相关的程序集。
5. 停止和取消所有相关的组件,比如接受位置、发送接口、编排。
6. 重新部署重新编译的程序集。记得一定要覆盖已存的程序集并将新的版本的程序集放入GAC。
7. 如果需要,导入早先导出的绑定。
8. 重启相关的主机实例。
9. 启动你的程序。
长事务或者不可接受短时间停机
如果你有长时间运行的编排并依赖你的架构,你不能更新没有版本化的架构。这是因为包含编排的程序集在所有运行实例结束前不能够卸载。因此,你必须终止所有的运行实例,或者停止接收的消息直到所有的运行实例结束运行,但是这可能会需要几天、几周、甚至几个月。两种场景都是不可接受的。
如果你没有长时间运行的编排,你可以停止你已经存在的功能以便不再接收新的消息,卸载已经存在的程序集,想前边讲的一样重新部署新的架构。
如果由于SLA(service level agreement)或者其他的原因,短时间的停机不可接受,不版本化机构就不能够升级。
为了版本化你的架构,你需要更改架构的首节点或者目标命名空间。