本文基於 .NET Framework 4.0 和 "Dublin" 的預發布版本。所有信息均有可能發生變更。
WF 活動程序庫和設計器
.NET Framework 4.0 中的 WCF 改進
"Dublin" 擴展指南
使用 "Dublin" 構建和部署服務
本文使用了以下技術:
.NET Framework 4.0、"Dublin"
在 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 工作流服務)的實現。
圖 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,因此您可以利用這一難得的機會來提出自己需要的更多活動。
.NET Framework 4.0 還引入了一些可提供更多流控制選項的核心活動,包括 FlowChart、ForEach、DoWhile 和 Break 等。新的 FlowChart 活動是最有趣的新增活動之一,它在 Sequential 和 StateMachine 流控制模型之間提供了一個不錯的折中方案。FlowChart 允許您使用一種分步方法,它可以實現一些簡單的決策和轉換功能,但它也允許在工作流中返回先前的活動。對許多用戶而言,流程圖通常看起來更為直觀。圖 3 顯示了 FlowChart 設計器在 Visual Studio 2010 的新工作流設計器中的外觀(有關詳細信息,請參閱“新工作流設計器”側欄。)
圖 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="http://schemas.microsoft.com/netfx/2009/xaml/workflowmodel" xmlns:p="http://schemas.microsoft.com/netfx/2008/xaml/schema" xmlns:s="clr-namespace:Samples;assembly=Samples" xmlns:x="http://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="http://schemas.microsoft.com/netfx/2009/xaml/workflowmodel" xmlns:p="http://schemas.microsoft.com/netfx/2008/xaml/schema" xmlns:s="clr-namespace:Samples;assembly=Samples" xmlns:x="http://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="http://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="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x2="http://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 所示。
圖 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" 提供的持久性提供程序和持久計時器服務對其進行了預配置。
圖 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" 擴展。
圖 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 配置文件。
圖 9 通過 "Dublin" 擴展查看和配置服務許多 Windows PowerShell cmdlet 都可用於執行這些任務,其中包括 Get-ServicePersistence、Set-ServicePersistence、Enable-ServiceTracking 和 Get-TrackingParticipant。這意味著自動化應用程序服務器環境的設置和配置要容易得多。
管理正在運行的應用程序
在應用程序的生命周期中,開發人員和系統管理員必須能夠監視應用程序的運行狀況、找出並查看存在問題的工作流實例並在必要時終止它們。"Dublin" 提供了大量可滿足這些常見管理需求的擴展。
如果在 IIS 管理器中選擇“Persisted Instances”(持久保存的實例)選項(請參見圖 8),您會看到一個儀表板視圖,其中將概述已持久保存且可能會被暫停的正在運行的工作流實例(請參見圖 10)。“Overview”(概述)框中將顯示部署到服務器、站點或應用程序(具體取決於所選的范圍)的應用程序和服務的總數。
圖 10 查看持久保存的工作流實例
“Persisted Instances”(持久保存的實例)框中將顯示正在運行且已持久保存的工作流實例的摘要,對它們的調用可能會被阻止或暫停(意味著它們由於某個錯誤而終止)。由於暫停的實例通常都是必須直接處理的實例,因此它們提供了一些其他的框,以便能夠根據虛擬路徑、服務名稱或異常類型輕松隔離特定的暫停實例。
可單擊任意鏈接(顯示為藍色字體)來顯示持久保存實例的列表並查看其詳細信息。此時,可通過選擇右側窗格中顯示的操作來手動暫停、終止或中止服務實例(請參見圖 11)。暫停服務實例可停止執行實例並阻止其接收新消息。稍後可恢復暫停的實例,此時它們將重新開始接收消息。終止服務實例可停止執行實例並從持久性存儲中將其刪除,這意味著它無法再恢復。最後,中止服務實例可清除內存中與指定實例相關的狀態並還原到上一個持久化點(它被存儲在持久性存儲中)。
圖 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 應用程序中進行監視。
.NET Framework 4.0 跟蹤體系結構中有兩個主要角色:跟蹤配置文件和跟蹤參與者。開發人員會定義跟蹤配置文件以告知運行時要跟蹤哪些事件,然後跟蹤參與者可以訂閱這些事件。
"Dublin" 附帶了一些內置的跟蹤配置文件,這使得跟蹤一組常見的有用事件變得非常輕松。通過導航到 IIS 管理器中的某個特定服務並在右側窗格中選擇“Tracking”(跟蹤),可以輕松實現對應用程序的跟蹤。
然後,您將看到圖 12 所示的對話框,通過它可以為工作流和服務配置一些基本的跟蹤功能。配置完畢後,將會對配置進行適當的更新,而 WCF/WF 跟蹤基礎結構也將會介入。
如果願意,您也可以通過 "Dublin" 擴展查看跟蹤數據。可在檢查持久保存服務實例的同時選擇“View Tracking Data”(查看跟蹤數據)(請參見圖 11),它將針對監視存儲運行 SQL 查詢,並為您生成要查看的跟蹤事件的列表(請參見圖 13)。如果想要跟蹤自定義事件,可通過主 IIS 管理器視圖上的“Tracking Profiles”(跟蹤配置文件)選項來定義自定義跟蹤配置文件並對其進行配置。
圖 12 配置基本跟蹤
圖 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 與他聯系。