引言
服務(Service)的本質(zhì)就是提供
服務消費者期望的某種功能,服務的價值體現(xiàn)在兩個方面:服務本身的質(zhì)量和寄宿服務的平臺應付消費者的數(shù)量,并發(fā)(Concurrency)的關注的是第二
個要素。WCF服務寄宿于資源有限的環(huán)境中,要實現(xiàn)服務效用的最大化,需要考慮如何利用現(xiàn)有的資源實現(xiàn)最大的吞吐量(Throughput)。提高吞吐量
就某個寄宿的服務實例(Service
Instance)來說,一個重要的途徑就是讓它能夠同時處理來自各個客戶端(服務代理)的并發(fā)訪問。WCF實現(xiàn)了一套完整的并發(fā)控制體系,為你提供了不
同的并發(fā)模式。
我經(jīng)常說軟件架構是一門權衡的藝術,需要綜合考慮各種相互矛盾的因素,找到一種最優(yōu)的組合方式。提高單個服務實例允許的
并發(fā)訪問量能夠提高整體吞吐量,這樣的理論依賴于一種假設,那就是服務端所能使用的資源是無限。我們知道,這種假設無論在什么情況下都不會成立。如果我們
并發(fā)量超出了服務端所能承受的臨界點,整個服務端將會崩潰。所以,WCF一方面需要允許讓單個服務實例并發(fā)處理接收到的多個請求,同時也需要設置一道閘門
控制并發(fā)的數(shù)量。WCF的流量限制(Throttling)體系為你創(chuàng)建了這道閘門。
從本篇文章開始,我將發(fā)布一系列的文章對WCF并發(fā)架構體系進行深入剖析 ,先來看看并發(fā)的基本介紹。
一、同一個服務實例上下文同時處理多個服務調(diào)用請求
并
發(fā)的含義就是多個并行的操作同時作用于一個相同的資源或者對象,或者說同一個資源或者對象同時應付多個并行的請求。對于WCF的并發(fā)來說,這里將的“資源
或者對象”指的就是承載服務操作最終執(zhí)行的服務實例(Service Instance)。而WCF將服務實例封裝在一個稱為實例上下文(InstanceContext)對象中,所以WCF中的并發(fā)指的是同一個服務實例上下文同時處理多個服務調(diào)用請求。
WCF服務端框架一個主要的任務是將接收到的服務調(diào)用請求分發(fā)給激活的服務實例,調(diào)用相應的服務操作并返回執(zhí)行結果。也就是說,服務操作的執(zhí)行最終還是會落實到某個具體的服務實例上。《WCF技術剖析(卷1)》
的第9章對WCF的實例化機制進行了深入的剖析,從中我們知道在WCF服務端框架體系中,激活的服務實例并不是單獨存在的,而是被封裝在一個被稱為實例上
下文(InstanceContext)對象中。WCF提供了三種不同的實例上下模式(Per-Call、Per-Session和Single)實現(xiàn)了
不同的服務實例上下文提供機制。
所以,WCF并發(fā)框架體系解決的是如何有效地處理被分發(fā)到同一個服務實例上下文的多個服務調(diào)用請求,這些并行的調(diào)用請求可能來自不同的客戶端(服務代理),也可能相同的客戶端。WCF并發(fā)的本質(zhì)上可以通過圖1體現(xiàn)。
圖1 通過一個InstanceContext對多個并發(fā)請求的處理
由于WCF的并發(fā)處理屬于服務本身自身的行為,所以我們通過服務行為(Service Behavior)的形式對采取的并發(fā)策略進行控制,而不同的并發(fā)策略定義在相應的并發(fā)模式(Concurrency Mode)下面。
二、通過ServiceBehaviorAttribute特性定義并發(fā)模式
WCF為三種典型的并發(fā)處理策略定義了三種典型的并發(fā)模式,即Single、Reentrant和Multiple。這三種并發(fā)模式通過ConcurrencyMode的三個同名的枚舉項表示,ConcurrencyMode定義如下:
1: public enum ConcurrencyMode
2: {
3: Single,
4: Reentrant,
5: Multiple
6: }
通過ConcurrencyMode枚舉項表示的三種不同的并發(fā)模式體現(xiàn)了WCF處理并發(fā)請求的三種不同能策略:
- Single:一個封裝了服務實例的InstanceContext對象在某個時刻只能用于對某一個單一請求的處理,或者說針對某個InstanceContext對象的多個并發(fā)的請求會以一種串行的方式進行處理。具體來講,當WCF服務端框架接收到多個針對相同InstanceContext的請求時,會先確定該InstanceContext是
否可用(是否正在處理之前的服務調(diào)用請求),如何可用,則將接收到的第一個請求分發(fā)給它,其它請求則被放入根據(jù)抵達的先后順序被放入到一個隊列中。如果之
前的請求被正常處理,隊列中的第一個請求被分發(fā)給InsanceContext。如果一個請求在隊列中等待的時間過長,超過了設置好的服務調(diào)用的超時實
現(xiàn),客戶端會跑出TimeoutException異常;
- Reentrant:該模式和Single一樣,InstanceContext對象在某個時刻只能用于對某一個單一請求的處理。不過有一點不同的是,如果服務操作在執(zhí)行過程中涉及對外調(diào)用(Call Out),該InstanceContext可以用于其它服務調(diào)用請求的處理;
- Multiple:在該模式下,一個InstanceContext可以同時用于處理多個服務請求,所以Multiple并發(fā)模式下針對同一個InstanceContext的多個并發(fā)請求能夠得到及時的處理。不過,由于是并行的處理方式,服務操作執(zhí)行過程中狀態(tài)的管理以及多線程的安全問題需要服務開發(fā)者自行處理。
并發(fā)模式的采用是服務單邊的選擇,是服務端個人的行為,所以并發(fā)模式以服務行為的方式定義,我們只需要在服務類型上應用
ServiceBehaviorAttribute特性,為ConcurrencyMode屬性設置相應的值即
可,ServiceBehaviorAttribute定義如下:
1: [AttributeUsage(AttributeTargets.Class)]
2: public sealed class ServiceBehaviorAttribute : Attribute, IServiceBehavior
3: {
4: //其它成員
5: public ConcurrencyMode ConcurrencyMode { get; set; }
6: }
如果顯示指定服務采用的并發(fā)模式,默認使用的是ConcurrencyMode.Single,所以下面兩種服務定義方式是等效的。
1: public class CalculatorService : ICalculator
2: {
3: //省略成員
4: }
5:
6: [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single)]
7: public class CalculatorService : ICalculator
8: {
9: //省略成員
10: }
三、回調(diào)(Callback)中的并發(fā)
WCF并發(fā)解決的是同一個InstanceContext對象在處理并發(fā)請求是采用怎樣的處理策略。我們知道InstanceContext不僅僅是封裝真正服務實例的容器,當我們通過雙向通信的機制從服務端回調(diào)客戶端操作時,真正執(zhí)行回調(diào)操作的回調(diào)對象也是封裝在InstanceContext中。
在雙向通信的場景中,如果多個服務端或者同一個客戶端的多個并發(fā)的服務調(diào)用操作所指定的回調(diào)實例上下文(即封裝回調(diào)操作的InstanceContext對象),就可能出現(xiàn)針對同一個InstanceContext的并發(fā)回調(diào)的現(xiàn)象。WCF采用與正常服務調(diào)用相同的機制來處理并發(fā)回調(diào),實際上WCF采用幾乎一樣的機制來實現(xiàn)正常的服務調(diào)用和回調(diào)。
與通過將ServiceBehaviorAttribute特性應用到服務類型并指定采用的并發(fā)模式相類似,回調(diào)采用的并發(fā)模式通過應用在回調(diào)類型上的CallbackBehaviorAttribute特性來指定。CallbackBehaviorAttribute中同樣定義了ConcurrencyMode屬性:
1: [AttributeUsage(AttributeTargets.Class)]
2: public sealed class CallbackBehaviorAttribute : Attribute, IServiceBehavior
3: {
4: //其它成員
5: public ConcurrencyMode ConcurrencyMode { get; set; }
6: }
下面的代用中,我們通過在回調(diào)類型CalculatorCallbackService上應用CallbackBehaviorAttribute特性,將回調(diào)并發(fā)模式設置成ConcurrencyMode.Multiple。
1: [CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
2: public class CalculatorCallbackService:ICalculatorCallback
3: {
4: //省略成員
5: }
四、 事務行為與并發(fā)
相信你還會記得在上面一章介紹事務編程(《上篇》、《中篇》、《下篇》)的時候,可以在服務類型上面應用ServiceBehaviorAttribute特性將ReleaseServiceInstanceOnTransactionComplete屬性設成True,這樣可以讓WCF在事務結束之后將封裝了服務實例的InstanceContext對象釋放掉。不過這樣的設置之后再并發(fā)模式為ConcurrencyMode.Single的前提下方才有效,否則在進行服務寄宿的時候將會拋出異常。
比如說,我們定了如下一個BankingService服務類型,通過ServiceBehaviorAttribute特性指定
ReleaseServiceInstanceOnTransactionComplete為True,并采用
ConcurrencyMode.Multiple并發(fā)模式。
1: [ServiceBehavior(ReleaseServiceInstanceOnTransactionComplete = true,ConcurrencyMode = ConcurrencyMode.Multiple)]
2: public class BankingService : IBankingService
3: {
4: [OperationBehavior(TransactionScopeRequired = true)]
5: public void Transfer(string accountFrom, string accountTo, decimal amount)
6: {
7: //省略實現(xiàn)
8: }
9: }
當我們試圖寄宿該BankingService服務的時候,如圖2所示的
InvalidOperationException異常會被拋出,并提示對于已經(jīng)將
ReleaseServiceInstanceOnTransactionComplete設置成True的服務來說,必須將并發(fā)模式設成
ConcurrencyMode.Multiple。
圖2 在Multiple+ReleaseServiceInstanceOnTransactionComplete導致的異常
WCF提供的三種不同的并發(fā)模式,使開發(fā)者可以根據(jù)具體的情況選擇不同的并發(fā)處理的策略。對于這三種并發(fā)模式,Multiple采用的并行的執(zhí)行方
式,而Single和Reentrant則是采用串行的執(zhí)行方式。串行執(zhí)行即同步執(zhí)行,在WCF并發(fā)框架體系中,這樣的同步機制是如何實現(xiàn)的呢?請關注下篇文章。
posted on 2010-12-26 11:24
小果子 閱讀(1301)
評論(0) 編輯 收藏 引用