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