入门

.NET Framework 4.0 和 "Dublin" 中的 WCF 和 WF 服务

Aaron Skonnard

本文基于 .NET Framework 4.0 和 "Dublin" 的预发布版本。所有信息均有可能发生变更。

本文将介绍以下内容:

  • WF 活动程序库和设计器
  • .NET Framework 4.0 中的 WCF 改进
  • "Dublin" 扩展指南
  • 使用 "Dublin" 构建和部署服务
本文使用了以下技术:
.NET Framework 4.0、"Dublin"

目录

转移到 .NET Framework 4.0

目录

WF 基本活动程序库

目录

WF 活动编程模型

目录

.NET Framework 4.0 中的更多新 WCF 功能

目录

"Dublin" 的必要性

目录

"Dublin" 指南

目录

针对 "Dublin" 构建 WCF 工作流服务

目录

使用 "Dublin" 部署应用程序

目录

管理正在运行的应用程序

目录

更新正在运行的应用程序

目录

监视正在运行的应用程序

目录

从 "Dublin" 到 "Oslo"?

目录

那对于 BizTalk Server 呢?

目录

在 2008 年 10 月份召开的专业开发人员大会 (PDC) 上,Microsoft 发布了有关 Microsoft .NET Framework 4.0 中将要提供的大量改进的详细信息,尤其是在 Windows Communication Foundation (WCF) 和 Windows Workflow Foundation (WF) 领域。Microsoft 还首次公开了对 Windows Server 的一些扩展(代号为 "Dublin"),它们可以为 WCF 和 WF 应用程序提供更好的托管和管理体验。

.NET Framework 4.0 中 WF 和 WCF 的集成将使开发面向服务的分布式应用程序变得更加简单。通过使用可以提供更大灵活性和业务敏捷性的完全声明性模型,您将能够构建有状态的工作流服务。

"Dublin" 所引入的新的托管和管理扩展将会完善这些框架改进。由于框架本身以及支持框架的操作工具这二者均有改进,因此 Windows Server 中的应用程序服务器的功能也将实现重大飞跃。

在本文中,我将探讨 .NET Framework 4.0 中 WCF 和 WF 的一些关键新功能以及 "Dublin" 扩展所提供的应用程序服务器的新功能。

转移到 .NET Framework 4.0

WCF 和 WF 属于互补技术。如果对它们不太熟悉,那么概括这对术语的一种简单说法就是:WCF 主外,WF 主内。WCF 用于公开应用程序的外部服务接口,而 WF 用于描述应用程序的内部流、状态和转换。

.NET Framework 3.5 在这二者之间引入了一些引入注目的集成,尤其是在 WF 的 Send 和 Receive 活动的形式方面。通过这些活动,您可以使用 WF 来简化协调多个服务交互的过程,以实现长时间运行的复杂工作流。通过使用 WCF 端点来启用这些活动,您也可以使用这些活动来扩展 WF 工作流的范围(请参见图 1)。这实质上是允许您将 WF 用作 WCF 服务(在本文中我将这样来称呼 WCF 工作流服务)的实现。

fig01.gif

图 1 WCF 工作流服务

尽管可以在 .NET Framework 3.5 中实现 WCF 工作流服务,但这却不是一件容易的事。对于初学者而言,WCF 和 WF 之间的集成层还有很大的改进空间。在 .NET Framework 3.5 中,必须使用 WCF 编程和配置模型来定义和配置 WCF 产物,而工作流的定义则要使用不同的模型。最终您会得到多个需要分别部署、配置和管理的产物。

让人感到困难的另一个原因是当前的基本活动程序库注重的是流控制和逻辑活动,而并未提供足够多的工作活动。因此,必须先编写一个自定义活动程序库,然后才能通过 WF 实现实际的工作流服务。由于该项工作太过复杂,有些开发人员在体验到 WF 的优点之前就已经放弃了努力。

除了这些问题以外,当前的 WF 还缺乏对仅使用可扩展应用程序标记语言 (XAML) 的工作流的工具支持,这些工作流也被称为声明性工作流,因为它们完全是通过 XML 文件进行描述的,没有任何源代码文件。“仅 XAML”方法引入了一些引人注目的工作流托管和部署可能性。对于声明性工作流而言,其优势在于只有能够存储在 WF 运行时环境中的任意位置且可以在其中执行的数据才知道所使用的活动。

声明性工作流可被部署到云的某个运行时中或桌面上的某个工作站中(假定活动已被部署到运行时主机)。声明性工作流还更易于实现版本控制,它们可用在部分信任的情形中(想一想“云”)。“仅含 XAML”模型也更易于构建相关的工具,因为这些工具仅用于处理 XML 文件。

通常情况下,“仅含 XAML”模型始终是 WF 作为一项技术而言的终极愿景,这一点在其架构师的早期著作中显而易见。但是,目前的 WF 工具支持并未完全实现该愿景。尽管可以使用 .NET Framework 3.5 构建“仅含 XAML”工作流,但必须围绕当前的 Visual Studio 模板展开工作而且不得不放弃一些重要功能(如调试)。

在 .NET Framework 4.0 中,WCF 和 WF 的主要目标是简化开发人员在声明性工作流和服务方面的体验,从而完全实现仅 XAML 模型。此外,Microsoft 还希望再前进一步,争取能够定义声明性工作流服务。也就是完全依照 XAML 定义的 WCF 服务,包括服务约定定义、端点配置和实际的服务实现(使用基于 XAML 的工作流的形式)。

为此,Microsoft 在 .NET Framework 4.0 中做了大量的改进,包括扩展的基类活动程序库、简化的自定义活动编程模型、全新的流程图工作流类型以及大量特定于 WCF 的改进。

WF 基本活动程序库

.NET Framework 4.0 提供了增强的基本活动程序库,其中包含多个新活动(请参见图 2)。Microsoft 还计划借助 CodePlex 在主要的 .NET Framework 版本之间逐步提供更多的 WF 活动。您还会逐渐看到更多的工作活动(如 PowerShellCommand 活动)出现在未来的版本中(或 CodePlex 上),从而降低开发自定义活动的需求。此外,由于 Microsoft 正在使用 CodePlex,因此您可以利用这一难得的机会来提出自己需要的更多活动。

fig02.gif

.NET Framework 4.0 还引入了一些可提供更多流控制选项的核心活动,包括 FlowChart、ForEach、DoWhile 和 Break 等。新的 FlowChart 活动是最有趣的新增活动之一,它在 Sequential 和 StateMachine 流控制模型之间提供了一个不错的折中方案。FlowChart 允许您使用一种分步方法,它可以实现一些简单的决策和转换功能,但它也允许在工作流中返回先前的活动。对许多用户而言,流程图通常看起来更为直观。图 3 显示了 FlowChart 设计器在 Visual Studio 2010 的新工作流设计器中的外观(有关详细信息,请参阅“新工作流设计器”侧栏。)

fig03.gif

图 3 新的 FlowChart 活动设计器

.NET Framework 4.0 还引入了一些新的运行时活动,可用于调用 CLR 方法 (MethodInvoke)、用于向工作流变量赋值 (Assign) 以及显式持久保持正在运行的工作流实例 (Persist)。

最后,.NET Framework 4.0 还提供了一组基于 WCF 的新活动,它们可以简化将工作流作为服务公开的过程或者在工作流中使用服务的过程。.NET Framework 3.5 提供了两个用于通过 WCF 发送和接收消息的活动(Send 和 Receive)。在版本 4.0 中,您会看到 SendMessage 和 ReceiveMessage 活动(用于发送和接收单向消息,类似于版本 3.5 中的 Send 和 Receive)以及通过 ClientOperation 和 ServiceOperation 活动实现的用于请求/响应操作的更高级抽象。想要公开某个服务操作的工作流应使用 ServiceOperation 活动。而想要使用外部服务的工作流则应使用 ClientOperation 活动。

除了这些核心 WCF 活动以外,.NET Framework 4.0 还支持不同的单向操作之间的关联,以确保特定消息能将其返回正确的工作流实例。它提供了一个用于定义新关联范围的活动 (CorrelationScope) 和用于在通过 WCF 发送出站消息之前初始化关联值的活动 (InitializeCorrelation)。

新工作流设计器

新增到 Visual Studio 2010 中的工作流设计器为本文中介绍的多个关键 WCF 和 WF 功能提供了引人注目的图形用户体验。它提供的功能包括改进的工作流导航(使用浏览路径记录功能在范围内往返,可深入到复合活动中)、就地活动编辑(减少了对“属性”窗口的需求)、缩放功能以及概述导航。此外,新的设计器针对自定义和重新托管提供了改进的模型。Visual Studio 2010 还将提供一组新的或改进的项目模板,可以更轻松地快速了解流程图和仅 XAML 工作流,并且在处理声明性工作流和服务时,它还会完全支持基于 XAML 的调试。

WF 活动编程模型

即使有了这些改进,有时可能仍然需要编写自定义活动。为使这一过程更加简单,Microsoft 重新设计了自定义活动的基类。新的自定义活动的基类被称为 WorkflowElement,另外还有一个从它派生而来的类,名为 Activity。使用 Activity 类可以轻松地根据现有活动创建新的自定义活动,而且即使需要编写代码的话,也不需要编写很多。

例如,图 4 显示了如何通过从 Activity 派生并重写 CreateBody 来定义一个名为 CopyFile 的新自定义活动。此实现将创建一个自定义的 PowerShellCommand 实例,并将其配置为使用内置的 copy-item 命令。如果希望完全避免此类代码,也可以使用 Visual Studio 2010 中的新工作流设计器,通过图形化活动设计器来轻松构建此类自定义活动。

图 4 自定义 CopyFile 活动

class CopyFile : Activity { public InArgument<string> Source { get; set; } public InArgument<string> Destination { get; set; } protected override WorkflowElement CreateBody() { return new PowerShellCommand { CommandText = "copy-item", Parameters = { { "path", new InArgument<string>(Source) }, { "destination", new InArgument<string>(Destination) } , { "recurse", new InArgument<bool>(false) } }, }; } }

如果需要从头开始(不基于现有活动)定义自定义活动,必须从 WorkflowElement 派生并重写 Execute 方法。此方法需要略微多一些的代码,这非常类似于现在从 Activity 派生时它的工作方式。但是,Microsoft 进一步简化了与编写这些自定义活动有关的事项。

使编写自定义活动处理起来比较麻烦的一件事是管理进出活动的数据流。例如,定义一组传入和传出某个活动的类型化参数目前是不可能的。通常情况下,开发人员会编写用于从工作流队列序列化和反序列化参数的自定义类(如需更多信息,请参阅 Michael Kennedy 撰写的文章“支持长时间运行操作的 Web 应用程序”)。编写此类探测代码并不困难,但这一额外工作会分散对应用程序流进行建模这一主要目标的注意力。.NET Framework 4.0 通过以下三个旨在显著简化操作的新数据流概念来扩展活动编程模型:参数、变量和表达式。

使用参数可定义数据流入和流出活动的方式。每个参数都有指定的绑定方向,如输入、输出或输入/输出。以下示例显示了如何通过名为 "AuditMessage" 的单个输入参数编写一个简单的 Audit 活动:

public class Audit: WorkflowElement { public InArgument<string> AuditMessage{ get; set; } protected override void Execute(ActivityExecutionContext context) { WriteToEventLog(AuditMessage.Get(context)); } }

变量可提供一种为数据声明已命名存储的方法。可在代码中和基于 XAML 的工作流中定义变量。也可以在工作流的不同范围内定义(在嵌套的工作流元素中),它们在设计时是工作流程序定义的一部分,而它们的值在运行时却存储在工作流实例中。

以下示例显示了如何编写一个 XAML 工作流,以使用它来定义一个名为 message 的变量、为其赋值(使用新的 Assign 活动),并随后将变量的值传递到先前定义的自定义 Audit 活动中:

<Sequence xmlns="https://schemas.microsoft.com/netfx/2009/xaml/workflowmodel" xmlns:p="https://schemas.microsoft.com/netfx/2008/xaml/schema" xmlns:s="clr-namespace:Samples;assembly=Samples" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"> <Sequence.Variables> <Variable Name="message" x:TypeArguments="p:String" /> </Sequence.Variables> <Assign x:TypeArguments="p:String" To="[message]" Value="Audit message: something bad happened" /> <s:Audit Text="[message]" /> </Sequence>

表达式这种构造可接受一或多个输入参数,并针对这些输入参数执行一些操作或行为,然后返回一个值。表达式是通过从 ValueExpression 派生类进行定义的,而 ValueExpression 本身又从 WorkflowElement 派生而来,因此在可以使用活动的任意位置都可以使用表达式。表达式也可用作对另一个活动参数的绑定。以下示例定义了一个简单的 Format 表达式:

public class Format : ValueExpression<string> { public InArgument<string> FormatString { get; set; } public InArgument<string> Arg { get; set; } protected override void Execute(ActivityExecutionContext context) { context.SetValue(Result, String.Format(FormatString.Get(context), Arg.Get(context))); } }

就像任何其他活动一样,可将这个表达式合并到您的 XAML 工作流中。例如,以下工作流展示了如何将 Format 表达式的结果传递到 Audit 活动中,以将结果写入事件日志(假定 Audit 的内容映射到 message 参数):

<Sequence xmlns="https://schemas.microsoft.com/netfx/2009/xaml/workflowmodel" xmlns:p="https://schemas.microsoft.com/netfx/2008/xaml/schema" xmlns:s="clr-namespace:Samples;assembly=Samples" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"> <Sequence.Variables> <Variable Name="message" x:TypeArguments="p:String" /> </Sequence.Variables> <s:Audit> <s:Format FormatString="Audit message: {0}" Arg="[message]"/> </s:Audit> </Sequence>

需要注意的另一件事情是根活动并没有任何特别之处。可在工作流的根或任意位置使用从 WorkflowElement 派生而来的任何内容。这将允许您在彼此间任意组合不同的工作流样式(例如,某个序列中流程图内的状态机)。

大部分此类编程模型变更都有助于使声明性工作流成为“一等公民”,因为您不再需要使用命令式代码隐藏文件来定义数据流属性——现在它们都可以使用 XAML 以声明方式完成。但是,由于这些都属于根本性的变更,因此它们需要对 WF 运行时进行某些重大改动,而这最终会破坏与 .NET Framework 3.x 活动的兼容性(更多信息,请参阅有关迁移工作流的侧栏)。尽管如此,Microsoft 仍相信随着时间的推移,WF 编程模型的简化一定会使 WF 开发人员受益匪浅。

将工作流迁移到 .NET 4.0

新的 .NET Framework 4.0 活动编程模型要求对核心 WF 运行时进行一些重大改动。因此,如果不采取一些特别措施,针对 .NET Framework 3.0 和 3.5 设计的自定义活动将无法在 .NET Framework 4.0 工作流主机中运行。

为便于实现互操作性,.NET Framework 4.0 附带了一个特殊的 Interop 活动,利用它可以轻松地将自定义的 .NET 3.x 活动封装在 .NET 4.0 主机中。此方法并不适用于所有 .NET 3.x 活动,尤其不适合根活动。因此,迁移到 Visual Studio 2010 时,需要使用新工作流设计器重新设计工作流(因为它也发生了极大的变化),然后可以使用新的 Interop 活动将自定义的 .NET 3.x 活动封装在新工作流定义中。

.NET Framework 4.0 中的更多新 WCF 功能

很容易就可以搞清如何使用工作流来实现 WCF 服务,但要真正生成声明性工作流服务,还需要有一种方法,它可以使用声明性的仅 XAML 模型来定义服务约定并配置端点定义。而这恰恰是 .NET Framework 4.0 中的 WCF 所带来的好处。假定有以下 WCF 服务约定定义:

[ServiceContract] public interface ICalculator { [OperationContract] int Add(int Op1, int Op2); [OperationContract] int Subtract(int Op1, int Op2); };

在 .NET Framework 4.0 中,可使用以下 XAML 定义通过声明方式定义同样的约定:

<ServiceContract Name="ICalculator"> <OperationContract Name="Add"> <OperationArgument Name="Op1" Type="p:Int32" /> <OperationArgument Name="Op2" Type="p:Int32" /> <OperationArgument Direction="Out" Name="res1" Type="p:Int32" /> </OperationContract> <OperationContract Name="Subtract"> <OperationArgument Name="Op3" Type="p:Int32" /> <OperationArgument Name="Op4" Type="p:Int32" /> <OperationArgument Direction="Out" Name="res2" Type="p:Int32" /> </OperationContract> </ServiceContract>

既然已经有了使用 XAML 定义的服务约定,接下来就要定义将约定投射到线路上的方式。.NET Framework 4.0 引入了约定投影这一概念,用来将逻辑约定定义与所发送和接收消息的表示分隔开来。这将允许您定义能够以不同方式进行投影以支持不同消息传送方式的单服务约定。

例如,可以将一个约定投影用于基于 SOAP 的消息传送,而将另一个投影用于 REST/POX 消息传送,但这二者均基于相同的逻辑服务约定。以下显示了如何为刚刚定义的服务约定定义 SOAP 约定投影:

<Service.KnownProjections> <SoapContractProjection Name="ICalculatorSoapProjection"> <!-- service contract definition goes here --> </SoapContractProjection> </Service.KnownProjections>

有了这个约定定义和投影后,您将能够使用 XAML 来实现服务逻辑了。XAML 服务定义的根元素是 Service。Service 元素将约定和投影定义保存在 Service.KnownProjections 子元素中。服务实现存在于 Service.Implementation 元素中(它是一个声明性工作流)。最后,服务的端点配置存在于 Service.Endpoints 元素中。图 5 显示了使用 XAML 实现的完整声明性服务定义。

图 5 声明性 WCF 服务

<Service xmlns="clr-namespace:System.ServiceModel;assembly=System.WorkflowServiceModel" xmlns:p="https://schemas.microsoft.com/netfx/2008/xaml/schema" xmlns:ss="clr-namespace:System.ServiceModel;assembly=System.ServiceModel" xmlns:sw="clr-namespace:System.WorkflowServiceModel;assembly=System.WorkfowServiceModel" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" xmlns:x2="https://schemas.microsoft.com/netfx/2008/xaml"> <Service.KnownProjections> <SoapContractProjection x:Name="ICalculatorSoapProjection"> <ServiceContract x:Name="ICalculatorContract" <OperationContract Name="Add" x:Name="Add"> <OperationArgument Name="Op1" Type="p:Int32" /> <OperationArgument Name="Op2" Type="p:Int32" /> <OperationArgument Direction="Out" Name="Result" Type="p:Int32" /> </OperationContract> </ServiceContract> </SoapContractProjection> </Service.KnownProjections> <Service.Implementation> <sw:WorkflowServiceImplementation> <!-- place service implementation here --> </sw:WorkflowServiceImplementation> </Service.Implementation> <Service.Endpoints> <Endpoint Uri="http://localhost:8080/calc" ContractProjection="{x2:Reference ICalculatorSoapProjection}"> <Endpoint.Binding> <ss:BasicHttpBinding /> </Endpoint.Binding> </Endpoint> </Service.Endpoints> </Service>

在这一早期阶段中存在的一个弊端是缺乏可视设计器来帮助以声明方式构建服务。希望随着社区预览版 (CTP) 的推出,Microsoft 会为处理 XAML 定义提供开发人员友好的设计体验。

除了之前提及的声明性服务支持和基于 WCF 的活动以外,.NET Framework 4.0 还附带了其他几个较低层的 WCF 改进。其中的一些功能使得通过新的 "Dublin" 扩展来管理工作流服务成为可能。这些功能包括改进的配置、消息关联、持久双工通信、持久计时器以及 Windows 事件跟踪 (ETW) 跟踪集成。在将服务托管到受控环境中时可实现增值的其他功能包括标准控制端点和自动启动。在未来的几个月里,您将了解到有关这些功能的更详细信息。

"Dublin" 的必要性

在现实环境中,使用 WCF 和 WF 时所面临的另一个挑战是确定将服务和工作流托管在服务器环境中的哪个位置。对于 WCF,答案通常很简单——最常见的选择是 IIS 和 Windows Server 2008 中的 Windows Process Activation Service (WAS)。

现在,IIS 和 WAS 的组合提供了多个关键功能,包括用于响应传入消息的进程激活、进程监控和运行状况管理、进程回收、CLR AppDomain 集成、内置安全性以及通过 IIS 管理器和 Windows PowerShell cmdlet 实现的一些基本管理功能。这些组合后的功能通常会使 IIS/WAS 成为在服务器环境中托管 WCF 服务的正确选择,因为大多数人都不希望自行构建此类功能。

尽管 IIS/WAS 为托管 WCF 应用程序提供了基础,但它在多个重要领域都存在缺陷。它最大的缺陷出现在服务可管理性领域。IIS/WAS 并未实际提供任何特定于 WCF 的服务管理功能,如服务跟踪、监视以及诊断正在运行的服务实例。例如,管理员目前还无法列出在 IIS 中配置的所有 WCF 服务——因为无法查询所有托管服务的状态。IIS/WAS 也并未针对简化扩展部署或常见的 WCF 配置任务提供内置支持,而这也正是 WCF 的痛处所在。

对于 WF 应用程序而言,在服务器环境中实现托管所面临的挑战更为严峻,因为它必须具有固有的有状态模型才能跨服务器场支持长时间运行的工作流。鉴于这些复杂的问题,Microsoft 并未在 .NET Framework 3.0 中提供 WF 服务器主机——开发人员必须自行编写。直到 .NET Framework 3.5 引入了 WorkflowServiceHost 类之后,才可以将 WF 工作流作为现成的 WCF 服务进行托管,从而使得在 IIS/WAS 中托管 WF 工作流成为可能。

WorkflowServiceHost 是一个良好的开端,但它并未附带用于跨整个 Web 服务器场来管理有状态工作流的任何工具支持,也未提供用于在运行时监视和管理正在运行的工作流实例的工具。

在服务和工作流管理功能方面,大多数开发人员都期望拥有类似于 BizTalk Server 所提供的、但却更简单的体验。许多组织都喜欢 BizTalk 管理体验,但他们并不需要集成 BizTalk Server MessageBox 中固有的功能或可靠性语义(以及相应的性能影响)。专门针对 WCF 和 WF 应用程序设计的轻型模型会更合适一些。

"Dublin" 指南

Microsoft 一直在研发 Windows Server 的一组新扩展(代号为 "Dublin"),它们可以为 WCF 和 WF 应用程序提供非常有价值的托管和管理功能。"Dublin" 实质上是基于 IIS/WAS 构建的一组服务管理扩展,将会作为 Windows Server 的一部分加以提供。使用 "Dublin" 扩展时,仍需要将服务和工作流托管在 IIS/WAS 中,但您的应用程序会享受到 IIS/WAS 中目前尚不具备的特定于 WCF 和 WF 的附加管理功能和工具。

各种 "Dublin" 扩展将作为 Windows Server 应用程序服务器角色的一部分随 Windows Server 的未来版本一起提供。因此,这组功能通常被称为“Windows 应用程序服务器”(尽管这并不是得到 Microsoft 认同的正式名称)。在本文的后续部分中,我将把这些新的 Windows Server 应用程序服务器扩展简称为 "Dublin"。

"Dublin" 扩展所提供的关键功能包括对可靠和持久服务以及长时间运行的工作流的管理支持。"Dublin" 使得将应用程序部署到场中的各个服务器成为可能,并且它还提供了完成特定服务管理任务所需的工具。我将在接下来的章节中更详细地介绍这些功能,首先让我们来看一下整个体系结构,如图 6 所示。

fig06.gif

图 6 "Dublin" 体系结构

正如您所看到的,"Dublin" 提供了多个运行时数据库,它们为实现服务持久性和监视功能奠定了基础。.NET Framework 提供了一层运行时组件和服务,它们都是以这些数据库为基础构建而成的。"Dublin" 将进一步扩展这些运行时以提供集成的托管、持久性、监视和消息传送功能。此层与底层运行时数据库相结合即构成了我们所说的 "Dublin"。

体系结构中最上面的两层是使 "Dublin" 能够为用户所用的接口。通过使用其中的管理 API 层,即可利用 Windows PowerShell cmdlet 编写各种功能的脚本。除此之外还有 IIS 管理器体验,如今的 IIS 管理员应该对之非常熟悉,因为它实际上是构建在 Windows PowerShell cmdlet 基础之上的。因此,所有可以在 IIS 管理器中执行的操作也都可以在 Windows PowerShell 中执行。

Microsoft 在 IIS 管理器中加入了大量 UI 扩展,可用来执行在本节中介绍的各种托管和管理任务。此外还有用于部署和配置应用程序、管理应用程序以及监视应用程序的扩展。这些扩展还提供了系统的运行时仪表板,用来显示诸如正在运行、暂停以及持久保存的工作流实例等信息。

针对 "Dublin" 构建 WCF 工作流服务

Visual Studio 2010 通过一个新的项目模板真正简化了构建以 "Dublin" 扩展作为目标的服务(如图 7 所示)。此项目模板提供了一个 web.config,事先已使用 "Dublin" 提供的持久性提供程序和持久计时器服务对其进行了预配置。

fig07.gif

图 7 创建新的 "Dublin" 服务库

生成项目之后,可将重点放在使用本文先前介绍的各项技术来实现 WCF 工作流服务上。新的工作流设计器体验使利用图形工作流开发方法实现整个服务成为可能。构建完整个工作流服务后,即可开始将该服务部署到通过 "Dublin" 扩展启用的 Windows Server 中。

可使用通常用于 Web 应用程序的任何技术将服务部署到 IIS/WAS(如果环境允许,可直接从 Visual Studio 进行部署)。也可以使用 Windows PowerShell cmdlet 来自动化这些任务。(这些 cmdlet 允许为 WCF 和 WF 环境构建自动化的部署脚本。如果想尝试使用其中的任何 cmdlet,只需在 Windows 应用程序服务器中打开 Windows PowerShell 并键入“help <命令>”,这样就可以了解到如何使用特定的命令。)部署完毕后,即可开始使用 IIS 管理器来访问图 8 中突出显示的各种 "Dublin" 扩展。

fig08.gif

图 8 IIS 管理器中的 "Dublin" 扩展

使用 "Dublin" 部署应用程序

出于安全性和隔离方面的考虑,许多环境并不允许开发人员直接将服务部署到受控服务器。"Dublin" 通过其应用程序导出/导入功能提供了一种用于部署服务的替代解决方案。

通过选择 IIS 管理器中的“Application Export”(应用程序导出)功能,可打包要部署到其他服务器上的 WCF 和 WF 应用程序。此时会显示一个对话框,要求您选择要导出的特定应用程序。指定一个位置后,按“Export”(导出),随即生成一个带有 .zip 扩展名的文件包,其中包含所有 WCF 和 WF 代码以及单个应用程序的所有元数据和配置设置。然后,可通过 "Dublin" 扩展将这一文件包移动并导入到另一个服务器上。现在,只需将 .zip 文件发送给负责管理服务器的 IT 专业人员让他处理即可。

Windows PowerShell Export-Application cmdlet 可实现相同的功能。此“Application Export”(应用程序导出)功能也非常适合于系统测试和验证环境。

可通过选择“Application Import”(应用程序导入)功能或使用 Import-Application cmdlet 来导入 WCF 和 WF 应用程序(也可以使用 Get-PackageManifest cmdlet 来查看文件包的内容)。然后,导入功能会提示您选择要导入的文件包(.zip 文件)。

在此过程中,如果需要,可指定应用程序名称、应用程序池以及应用程序的物理路径。并且,由于 "Dublin" 提供集中的持久性配置,因此在将工作流服务部署到另一个服务器时,不必担心在应用程序级更改持久性配置的问题。它会直接使用与新服务器相关联的新持久性数据库。对于负责在服务器环境中部署 WCF 和 WF 应用程序的系统管理员而言,这些功能使得部署过程变得异常便捷。

成功部署了应用程序后,即可开始通过 "Dublin" 提供的其他扩展来配置服务。例如,在某些情况下,系统管理员可能需要手动重新配置持久性和跟踪数据库的运行时配置。使用 "Dublin" 扩展,此操作将非常简单。只需从默认视图中选择“Services”(服务),屏幕就会显示所有受控服务的列表,同时右侧窗格会公开各种服务配置选项(请参见图 9)。通过使用这些选项,您可以轻松地更改持久性设置、跟踪设置以及与安全性和限制相关的其他 WCF 设置。而您根本不必操作 WCF 配置文件。

fig09.gif

图 9 通过 "Dublin" 扩展查看和配置服务

许多 Windows PowerShell cmdlet 都可用于执行这些任务,其中包括 Get-ServicePersistence、Set-ServicePersistence、Enable-ServiceTracking 和 Get-TrackingParticipant。这意味着自动化应用程序服务器环境的设置和配置要容易得多。

管理正在运行的应用程序

在应用程序的生命周期中,开发人员和系统管理员必须能够监视应用程序的运行状况、找出并查看存在问题的工作流实例并在必要时终止它们。"Dublin" 提供了大量可满足这些常见管理需求的扩展。

如果在 IIS 管理器中选择“Persisted Instances”(持久保存的实例)选项(请参见图 8),您会看到一个仪表板视图,其中将概述已持久保存且可能会被暂停的正在运行的工作流实例(请参见图 10)。“Overview”(概述)框中将显示部署到服务器、站点或应用程序(具体取决于所选的范围)的应用程序和服务的总数。

fig10.gif

图 10 查看持久保存的工作流实例

“Persisted Instances”(持久保存的实例)框中将显示正在运行且已持久保存的工作流实例的摘要,对它们的调用可能会被阻止或暂停(意味着它们由于某个错误而终止)。由于暂停的实例通常都是必须直接处理的实例,因此它们提供了一些其他的框,以便能够根据虚拟路径、服务名称或异常类型轻松隔离特定的暂停实例。

可单击任意链接(显示为蓝色字体)来显示持久保存实例的列表并查看其详细信息。此时,可通过选择右侧窗格中显示的操作来手动暂停、终止或中止服务实例(请参见图 11)。暂停服务实例可停止执行实例并阻止其接收新消息。稍后可恢复暂停的实例,此时它们将重新开始接收消息。终止服务实例可停止执行实例并从持久性存储中将其删除,这意味着它无法再恢复。最后,中止服务实例可清除内存中与指定实例相关的状态并还原到上一个持久化点(它被存储在持久性存储中)。

fig11.gif

图 11 查看各个持久保存的实例

Windows PowerShell Get-ServiceInstance 和 Stop-ServiceInstance cmdlet 通过命令行提供了相同的功能;它们提供了大量用于确定特定服务实例的命令行选项。

更新正在运行的应用程序

处理实际的系统时会遇到的一个特别麻烦的问题就是需要定期更新它们。对于大多数复杂的分布式应用程序而言,当所做的必要更改需要同时更新到数据库、业务逻辑以及服务代码时,要正确实现这一点可能比较棘手。通常情况下,在应用程序运行的同时以原子方式应用重大更新是不可能的。

解决此问题的一种方法是在执行更新时使应用程序处于脱机状态。但是,如果真想要使用这种方法,在对网站执行更新的同时使 IIS/WAS 应用程序脱机也不是一件容易的事。而这恰好是 "Dublin" 扩展通过一个简单的脱机功就能实现增值的另一个方面。

可在 IIS 管理器中选择一个应用程序,然后在图 8 所示的右侧窗格中选择“Disable Protocols”(禁用协议)命令(必须要注意,在未来的版本中,它可能会被重命名)。执行此操作后,应用程序服务的所有实例或处于受阻状态,或正常完成执行,而且不允许处理任何新的传入请求。

此时,基本上已经停止了此应用程序的消息流,这意味着客户端再向服务发送消息将收到错误提示(它们不会像在 BizTalk Server 中一样进行排队等候)。这其中的工作原理非常简单:"Dublin" 扩展删除了这个特定应用程序的所有协议处理程序并将它们保存起来,这样,在更新完毕后即可非常轻松地恢复它们。

应用程序处于脱机状态后,您即可执行所需的任何更新。完成更新并做好让应用程序重新联机的准备后,可选择“Restore Protocols”(恢复协议)命令。Windows PowerShell Disable-ApplicationMessageFlow 和 Enable-ApplicationMessageFlow cmdlet 也可用于通过命令行执行这些相同的任务。

监视正在运行的应用程序

企业还需要具备监视正在运行的应用程序的能力,以便了解企业的运行状况以及需要进行哪些变更。WCF 和 WF 运行时已附带了内置的跟踪基础结构("Dublin" 扩展就构建在其中),从而可以很轻松地在 WCF 和 WF 应用程序中进行监视。

fig12.gif

图 12 配置基本跟踪

.NET Framework 4.0 跟踪体系结构中有两个主要角色:跟踪配置文件和跟踪参与者。开发人员会定义跟踪配置文件以告知运行时要跟踪哪些事件,然后跟踪参与者可以订阅这些事件。

"Dublin" 附带了一些内置的跟踪配置文件,这使得跟踪一组常见的有用事件变得非常轻松。通过导航到 IIS 管理器中的某个特定服务并在右侧窗格中选择“Tracking”(跟踪),可以轻松实现对应用程序的跟踪。

然后,您将看到图 12 所示的对话框,通过它可以为工作流和服务配置一些基本的跟踪功能。配置完毕后,将会对配置进行适当的更新,而 WCF/WF 跟踪基础结构也将会介入。

如果愿意,您也可以通过 "Dublin" 扩展查看跟踪数据。可在检查持久保存服务实例的同时选择“View Tracking Data”(查看跟踪数据)(请参见图 11),它将针对监视存储运行 SQL 查询,并为您生成要查看的跟踪事件的列表(请参见图 13)。如果想要跟踪自定义事件,可通过主 IIS 管理器视图上的“Tracking Profiles”(跟踪配置文件)选项来定义自定义跟踪配置文件并对其进行配置。

fig13.gif

图 13 查看跟踪数据

由于篇幅所限,我在此无法介绍所有的 "Dublin" 功能,还有许多其他引人注目的功能值得我们进一步讨论(如需详细信息,请参阅“其他的 Dublin 功能”侧栏),但我希望您已经比较清楚地了解了 "Dublin" 的作用以及它将会提供的一些关键功能。

从 "Dublin" 到 "Oslo"?

如果您曾听说过代号为 "Oslo" 的平台,那么您很可能会想知道 "Dublin" 与该计划之间的关系。首先,"Oslo" 是一个由 Microsoft 开发的全新建模平台,用于简化设计、构建和管理分布式应用程序的方式。该建模平台包含三个主要组件:"Oslo" 建模语言(也称为 "M")、"Oslo" 存储库以及 "Oslo" 建模工具(也称为 "Quadrant")。"Oslo" 实际上是一个平台,其他应用程序和技术可使用它作为构建基础并可以通过一种模型驱动方法来简化用户体验。

其他 "Dublin" 功能

"Dublin" 还有一些因篇幅所限而未能在本文中详细介绍的其他功能。但值得一提的是它支持在与现有负载平衡解决方案(如用于通过集中式持久数据库来管理整个场中的持久保存服务实例的哪些解决方案)相集成的服务器场之间进行扩展部署。内置的错误处理逻辑允许在场中的任意节点上执行持久保存的实例,并可避免在多个节点争夺相同实例时出现争用条件。

另一个重要组件是“转发服务”。通过此服务可截取所有传入消息,从而能够根据消息内容来执行集中路由。尤其值得一提的是,此功能为构建复杂的服务版本管理解决方案提供了不错的基础。

"Dublin" 还具有一些用于管理服务实例生命周期的关键服务,包括“持久计时器服务器”和“实例重启服务”。"Dublin" 还知道如何充分利用 .NET Framework 4.0 提供的“实例控制端点”和全新的 IIS/WAS 自动启动功能(利用此功能可以在机器启动时启动服务,而不必等到第一条消息出现后再启动)。在接下来的几个月里将会出现更多有关这些功能的文章。

"Dublin" 将成为最先利用 "Oslo" 建模平台的技术之一。您将能够从存储库导出 "Oslo" 应用程序并轻松地将其部署到 "Dublin",从而能够从本文讨论的各种托管和管理功能中受益。对于复杂的 IT 环境而言,利用模型来描述和自动化应用程序部署可以看作是一场胜利。

随着 "Dublin" 和 "Oslo" 逐渐成熟,这两项技术之间的集成很可能会继续深入。Microsoft 已宣布了它的目标,即这两项技术将建立相互依赖的互补关系。

那对于 BizTalk Server 呢?

另一个常见的问题是 "Dublin" 与 BizTalk Server 之间是什么关系。对于今天的 "Dublin" 中包含的很多功能而言,其灵感都来自于 BizTalk Server。尽管这两项技术都提供了类似的管理功能,但二者在各自的侧重点方面却存在着巨大的差异。"Dublin" 在 Windows Server 添加了专为 WCF 和 WF 应用程序而设计的托管和管理扩展,而 BizTalk Server 主要是使用各种不同的消息格式、传输和映射技术实现与非 Microsoft 系统的应用程序的集成。

BizTalk Server 的关注点无论是在过去还是在将来始终都是实现与非 Microsoft 系统(业务线应用程序、旧系统、RFID 设备以及企业间协议)的集成。在未来的几年内,BizTalk Server 仍会专注于这些核心优势。一般来说,如果用户主要关注的是这些类型的企业应用程序集成 (EAI) 情形,则会希望继续使用 BizTalk Server。

但是,由于许多 WCF 和 WF 应用程序都不需要此类集成功能,因此 BizTalk Server 常常让人感觉有点多余。而这恰好是 "Dublin" 的长处所在——可以提供类似的管理功能但相对而言却更为简单。最后,对于这些情形,"Dublin" 比 BizTalk Server 更具成本效益,因为 "Dublin" 扩展将作为 Windows Server 的核心部分提供,不需要您购买多余的集成适配器。很可能 BizTalk Server 的未来版本会构建在 "Dublin" 扩展的基础上,以便充分利用对 Windows Server 所做的核心管理投资。

特别感谢 Eileen Rumwell、Mark Berman、Dino Chiesa、Mark Fussell、Ford McKinstry、Marjan Kalantar、Cliff Simpkins、Kent Brown、Kris Horrocks 以及 Kenny Wolf 对本文提供的大力协助。

Aaron Skonnard 是 Microsoft .NET 的首席培训提供商 Pluralsight 的创始人之一,该公司提供教师引导式课程以及在线培训课程。Aaron 曾撰写过许多书籍、白皮书和文章,并曾撰写了 Pluralsight 在 REST、Windows Communication Foundation 以及 BizTalk Server 方面的培训课程。您可以通过 pluralsight.com/aaron 与他联系。