Programming WCF Services 学习笔记四、Instance Management
??? 1.???????? Behaviors
???????????????????????? i.????????????? Service的實(shí)例模型是客戶端無關(guān)的,即Client端不會知道Service的實(shí)例模型,Service的實(shí)例模型也不會影響Client端
?????????????????????? ii.????????????? 通過ServiceBehavior Attribute可以設(shè)定Service的實(shí)例模型
????????????????????? iii.????????????? OperationBehavior Attribute設(shè)定OperationContract的行為
三種實(shí)例模型
2.???????? PerCall:
???????????????????????? i.????????????? 每次一個(gè)新的調(diào)用到來時(shí),WCF會創(chuàng)建一個(gè)新的Service實(shí)例進(jìn)行服務(wù),調(diào)用結(jié)束時(shí)銷毀實(shí)例
?????????????????????? ii.????????????? PerCall的好處
1.???????? 傳統(tǒng)的CS模式是每個(gè)Client長期占用一個(gè)Service實(shí)例,直至Client停止,這樣專用的方式很浪費(fèi)Service實(shí)例
2.???????? 一個(gè)好的辦法是直到一個(gè)Client的Call到來時(shí)才創(chuàng)建一個(gè)Service實(shí)例,Call結(jié)束時(shí)就銷毀實(shí)例,這樣使得Service實(shí)例的數(shù)目不再是Client的所有數(shù)目,而是同時(shí)調(diào)用(并發(fā)訪問)的數(shù)目
3.???????? 使用
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)]指定使用PerCall實(shí)例模型
4.???????? 因?yàn)?/span>PerCall是在每次Call時(shí)創(chuàng)建一個(gè)新的實(shí)例,Call完就銷毀實(shí)例,所以需要一個(gè)保存狀態(tài)的機(jī)制(Call之前Load狀態(tài),Call之后保存狀態(tài))
5.???????? 因?yàn)?/span>PerCall每次會創(chuàng)建/銷毀新的實(shí)例,還需要一個(gè)Instance的ID標(biāo)識要獲得/保存哪個(gè)Instance的狀態(tài)
6.???????? PerCall在兩種情況下工作最佳
1.???????? 每一次Call所做的事情沒有關(guān)聯(lián)性
2.???????? 沒有幕后的工作要做(異步)
7.???????? PerCall適合負(fù)載均衡的場合,能在多臺機(jī)器之間負(fù)載
8.???????? PerCall在性能(創(chuàng)建實(shí)例)和可測量性(資源占用)之間做了一個(gè)平衡,要根據(jù)具體情況而定
9.???????? 使用PerCall時(shí),不要為ServiceContract添加Cleanuup()之類的方法,即Client不能執(zhí)行Cleanup的工作
10.???? PerCall的最大優(yōu)點(diǎn)是可擴(kuò)容性,他可以容納更多的Client調(diào)用,而且PerCall可以很好地參與事務(wù)
3.???????? PerSession
a)???????? WCF可以在一個(gè)Client(Proxy)和一個(gè)Service Instance之間維持一個(gè)Session
b)???????? PerSession和經(jīng)典的C/S模式很像。優(yōu)點(diǎn)是可以保存狀態(tài),隔離性。缺點(diǎn)是專屬Session,可擴(kuò)容性差
c)???????? PerSession是默認(rèn)的實(shí)例模型
d)???????? PerSession狀態(tài)下,Session在Proxy close時(shí)被Close
e)???????? Proxy被Close時(shí)需要通知Service,所以Service要標(biāo)識Proxy。WCF可以使用Transport-level session
f)????????? NetTcpBinding,NetNamedPipeBinding支持Transport-level session
g)???????? WSHttpBinding可以通過在消息頭中包含Session ID來達(dá)到同樣的目的
h)???????? 還可以在ServiceContract上指定SessionMode=SessionMode.Allowed,指定ServiceContract使用PerSession模型。但最終是使用哪種模型,還是取決于ServiceBehavior和協(xié)議
i)?????????? 通過指定SessionMode=SessionMode.Required指定ServiceContract必須使用PerSession,但如果使用不支持Transport-level session的協(xié)議,WCF會在運(yùn)行時(shí)報(bào)錯,但ServiceBehavior設(shè)為PerCall時(shí)會使用PerCall
j)?????????? 通過制定SessionMode=SessionMode.NotAllowed指定ServiceContract不能使用Transport-level session的協(xié)議,它強(qiáng)制適應(yīng)PerCall,如果使用TCP或IPC協(xié)議,WCF會在運(yùn)行時(shí)報(bào)錯。而WSHttpBinding可以使用
k)???????? 較為好的辦法是使用NotAllowed時(shí),ServiceBehavior設(shè)為PerCall
| Table 4-1. Instance mode as a product of the binding, contract configuration, and service behavior | ||||
| Binding | Session mode | Context mode | Async Dispose() | Instance mode |
| Basic | Allowed/NotAllowed | PerCall/PerSession | Yes | PerCall |
| TCP, IPC | Allowed/Required | PerCall | No | PerCall |
| TCP, IPC | Allowed/Required | PerSession | Yes | PerSession |
| WS (no security, no reliability) | NotAllowed/Allowed | PerCall/PerSession | Yes | PerCall |
| WS (with security or reliability) | Allowed/Required | PerSession | Yes | PerSession |
| WS (with security or reliability) | NotAllowed | PerCall/PerSession | Yes | PerCall |
l)?????????? 當(dāng)使用PerSession時(shí),Session的可靠性是依賴于Transport的可靠性的,所以盡量開啟可靠消息傳輸
m)?????? SessionID用來表示當(dāng)前的Session。Service端通過OperationContext.Current.SessionId取得,Client端通過Proxy.InnerChannel.SessionId取得
n)???????? 取得Session的策略
?????????????????????????????????????????????????????????????????? i.????????????? 當(dāng)使用TCP協(xié)議并啟用可靠消息傳輸時(shí),Session在第一次Call之后獲得,之前獲得的是null。
???????????????????????????????????????????????????????????????? ii.????????????? 當(dāng)使用TCP協(xié)議但未啟用可靠消息傳輸時(shí),Client可以在Call之前取得SessionID,但SessionID不會匹配任何Service
??????????????????????????????????????????????????????????????? iii.????????????? 當(dāng)使用WS Binding,并啟用可靠消息傳輸時(shí),在第一次Call之前,SessionID為Null
??????????????????????????????????????????????????????????????? iv.????????????? 當(dāng)使用WS Binding,但不啟用可靠消息傳輸時(shí),必須先Open Proxy,否則會報(bào)異常,Open之后,SessionID可用
???????????????????????????????????????????????????????????????? v.????????????? NamedPipe Binding時(shí),第一次Call之前就能取得SessionID,但SessionID不匹配Service,無意義
??????????????????????????????????????????????????????????????? vi.????????????? 當(dāng)Client端Proxy10(默認(rèn))分鐘無任何動作時(shí),Session失效,可以修改超時(shí)時(shí)間。在reliableSession中的inactivityTimeout中設(shè)定
????????????????????????????????????????????????????????????? vii.????????????? 當(dāng)Client和Service都設(shè)定超時(shí)時(shí)間時(shí),取其短
4.???????? Singleton
???????????????????????? i.????????????? 所有的Client獨(dú)立地連接到同一個(gè)Service Instance,盡管他們連接到不同的Endpoint。Singleton Service Instance在Host創(chuàng)建時(shí)創(chuàng)建,在Host 關(guān)閉時(shí)銷毀。
?????????????????????? ii.????????????? Singleton不要求Session。當(dāng)ServiceContract需要Session時(shí),Service Instance會維護(hù)一個(gè)Session(SessionID同Client相同),當(dāng)Client Proxy關(guān)閉時(shí),Session被關(guān)閉,但Service Instance依然存在。而且Session不會過期。
????????????????????? iii.????????????? 如果想自己創(chuàng)建Singleton Instance并自定義初始化操作,WCF提供了一種方式:ServiceHost的一個(gè)構(gòu)造函數(shù)接受Object類型的Singleton Instance,可以傳遞一個(gè)自己創(chuàng)建的對象傳給ServiceHost。并且可以在Service對象的SingletonInstance屬性取得此Instance。在代碼鏈中,可以通過OperationContext.Current.Host. SingletonInstance取得。
????????????????????? iv.????????????? Singleton十分不利于擴(kuò)容性。原因是狀態(tài)同步。Singleton讓多個(gè)Client共享一個(gè)Service Instance,需要管理多個(gè)Client并發(fā),狀態(tài)同步,這樣會降低性能。
?????????????????????? v.????????????? Singlet適用于像日志這樣的只需一個(gè)對象的場景,不使用于可能服務(wù)于多個(gè)Client,并且Client可能增加的場景。
5.???????? Demarcating Operations
???????????????????????? i.????????????? 在需要Session的ServiceContract中,有時(shí)需要某個(gè)方法最先被調(diào)用,或某個(gè)方法最后被調(diào)用,WCF使用OperationContract Attribute的IsInitiating和IsTerminating標(biāo)識Service邊界。
?????????????????????? ii.????????????? 如果這兩個(gè)Property被設(shè)置為非默認(rèn)值,在Service Load時(shí),WCF會檢驗(yàn)方法所在地ServiceContract是否支持Session,如果不支持,會報(bào)異常。PerSession和Singleton都支持Demarcating Operation。
6.???????? Instance Deactivation
???????????????????????? i.????????????? 在需要Session的ServiceContract中,WCF允許在某個(gè)方法上指定調(diào)用之前或之后銷毀當(dāng)前Service Instance。
?????????????????????? ii.????????????? 通過在方法上使用ReleaseInstanceMode枚舉,指定行為。
????????????????????? iii.????????????? 不能在每個(gè)方法上都是用它,因?yàn)檫@樣就和PerCall相同了。
????????????????????? iv.????????????? 可以使用Demarcating Operation指定銷毀Instance的順序。
?????????????????????? v.????????????? 當(dāng)ReleaseInstanceMode被設(shè)為BeforCall時(shí),方法調(diào)用前,Client被阻塞,WCF首先銷毀當(dāng)前Session中存在的Service Instance(調(diào)用Dispose),再調(diào)用方法。
????????????????????? vi.????????????? 當(dāng)ReleaseInstanceMode被設(shè)為BeforAndAfterCall時(shí),在調(diào)用方法前后,都會銷毀當(dāng)前的Instance然后創(chuàng)建一個(gè)新的。它可以用在BeforCall之后,或AfterCall之前,用來模擬PerCall的情況。
??????????????????? vii.????????????? 除了使用Attribute在設(shè)計(jì)時(shí)指定之外,還可以調(diào)用InstanceContext.ReleaseServiceInstance()在運(yùn)行時(shí)釋放Service Instance。而且可以和Attribute合作,BeforCall Attribute+方法結(jié)尾時(shí)調(diào)用InstanceContext.ReleaseServiceInstance()相當(dāng)于BeforAndAfterCall Attribute。
?????????????????? viii.????????????? Instance Deactivation是一個(gè)優(yōu)化的技術(shù),就像所有的優(yōu)化技術(shù)一樣,盡量避免把它使用到普通場景下。Instance Deactivation使用在遇到性能和可擴(kuò)容性共同存在是時(shí)比較有效,并且可以得到一些改善。但如果可擴(kuò)容行和吞吐量是你所關(guān)心的指標(biāo)的話,盡量使用PerCall方式,而避免使用Instance Deactivation。
7.???????? Throttling
???????????????????????? i.????????????? Throttling允許WCF抑制Client連接和負(fù)載。通過設(shè)置Throttling,可以控制Service服務(wù)的Client的數(shù)量和Service訪問的資源。
?????????????????????? ii.????????????? Throttling通過把超出規(guī)定數(shù)目的Client請求入隊(duì)來抑制Client的連接,如果一個(gè)Client Call在出隊(duì)之前就超時(shí)的話,Client會得到超時(shí)異常。
????????????????????? iii.????????????? Throttling使用于各種Service實(shí)例模型,即對所有的Service都有效。
????????????????????? iv.????????????? Throttling通過Channel Dispatcher起作用
?????????????????????? v.????????????? Throttling的幾種情況
1.???????? Session的并發(fā)數(shù):在啟用Session時(shí),可以設(shè)置每個(gè)Session可以同時(shí)服務(wù)的Client數(shù)目,默認(rèn)是10個(gè)。但這種設(shè)置對不起用Session的情況無效。
2.???????? 調(diào)用(Call)的并發(fā)數(shù):所有Instance服務(wù)的Client Call的并發(fā)數(shù),默認(rèn)是16個(gè)。
3.???????? Instance的并發(fā)數(shù):同時(shí)存在的Instance Context的數(shù)目,默認(rèn)無限制。Context的數(shù)目和Instance的數(shù)目是不一樣的,取決于Instance Deactivation的設(shè)置。
4.???????? 在PerSession Service中,Instance的最大數(shù)目取決于Instance的并發(fā)數(shù)和Session的并發(fā)數(shù)。當(dāng)Instance Deactivation被使用時(shí),Instance的數(shù)目會少于Context的數(shù)目(因?yàn)?/span>Instance可能會在Call之后被銷毀)。但是當(dāng)Context的數(shù)目達(dá)到Instance的并發(fā)數(shù)目時(shí),Client會被阻塞。
5.???????? 在PerCall Service中,Instance的數(shù)目就是Call的并發(fā)數(shù)。
6.???????? Throttling對Singleton無效。
????????????????????? vi.????????????? 配置Throttling
1.???????? 在Behaviors節(jié)ServiceBehaviors中ThrottledBehavior中設(shè)置ServiceThrottling的MaxConcurrentCalls,MaxConcurrentSessions,MaxConcurrentInstances。
2.???????? 編程方式:設(shè)置
host.Description.Behaviors.Find<ServiceThrottlingBehavior>( );
??????????????????? vii.????????????? Binding的Throttling
1.???????? 可以在TCP和NamePipe Binding中設(shè)置MaxConnections,如果Binding和Service同時(shí)設(shè)置,WCF取其最小值。
(未完待續(xù))
轉(zhuǎn)載于:https://www.cnblogs.com/zhaojunqi/archive/2008/06/03/1212872.html
總結(jié)
以上是生活随笔為你收集整理的Programming WCF Services 学习笔记四、Instance Management的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [转帖]最新FLASH 0DAY 漏洞总
- 下一篇: ASP.NET2.0 - skmMenu