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会创建一个新的Service实例进行服务,调用结束时销毁实例

                       ii.              PerCall的好处

1.         传统的CS模式是每个Client长期占用一个Service实例,直至Client停止,这样专用的方式很浪费Service实例

2.         一个好的办法是直到一个ClientCall到来时才创建一个Service实例,Call结束时就销毁实例,这样使得Service实例的数目不再是Client的所有数目,而是同时调用(并发访问)的数目

3.         使用

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)]指定使用PerCall实例模型

4.         因为PerCall是在每次Call时创建一个新的实例,Call完就销毁实例,所以需要一个保存状态的机制(Call之前Load状态,Call之后保存状态)

5.         因为PerCall每次会创建/销毁新的实例,还需要一个InstanceID标识要获得/保存哪个Instance的状态

6.         PerCall在两种情况下工作最佳

1.         每一次Call所做的事情没有关联性

2.         没有幕后的工作要做(异步)

7.         PerCall适合负载均衡的场合,能在多台机器之间负载

8.         PerCall在性能(创建实例)和可测量性(资源占用)之间做了一个平衡,要根据具体情况而定

9.         使用PerCall,不要为ServiceContract添加Cleanuup()之类的方法,Client不能执行Cleanup的工作

10.     PerCall的最大优点是可扩容性,他可以容纳更多的Client调用,而且PerCall可以很好地参与事务

3.         PerSession

a)         WCF可以在一个Client(Proxy)和一个Service Instance之间维持一个Session

b)         PerSession和经典的C/S模式很像。优点是可以保存状态,隔离性。缺点是专属Session,可扩容性差

c)         PerSession是默认的实例模型

d)         PerSession状态下,SessionProxy close时被Close

e)         ProxyClose时需要通知Service,所以Service要标识ProxyWCF可以使用Transport-level session

f)          NetTcpBindingNetNamedPipeBinding支持Transport-level session

g)         WSHttpBinding可以通过在消息头中包含Session ID来达到同样的目的

h)         还可以在ServiceContract上指定SessionMode=SessionMode.Allowed,指定ServiceContract使用PerSession模型。但最终是使用哪种模型,还是取决于ServiceBehavior和协议

i)           通过指定SessionMode=SessionMode.Required指定ServiceContract必须使用PerSession,但如果使用不支持Transport-level session的协议,WCF会在运行时报错,但ServiceBehavior设为PerCall时会使用PerCall

j)           通过制定SessionMode=SessionMode.NotAllowed指定ServiceContract不能使用Transport-level session的协议,它强制适应PerCall,如果使用TCPIPC协议,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用来表示当前的SessionService端通过OperationContext.Current.SessionId取得,Client端通过Proxy.InnerChannel.SessionId取得

n)         取得Session的策略

                                                                   i.              当使用TCP协议并启用可靠消息传输时,Session在第一次Call之后获得,之前获得的是null

                                                                 ii.              当使用TCP协议但未启用可靠消息传输时,Client可以在Call之前取得SessionID,但SessionID不会匹配任何Service

                                                                iii.              当使用WS Binding,并启用可靠消息传输时,在第一次Call之前,SessionIDNull

                                                                iv.              当使用WS Binding,但不启用可靠消息传输时,必须先Open Proxy,否则会报异常,Open之后,SessionID可用

                                                                 v.              NamedPipe Binding时,第一次Call之前就能取得SessionID,但SessionID不匹配Service,无意义

                                                                vi.              ClientProxy10(默认)分钟无任何动作时,Session失效,可以修改超时时间。在reliableSession中的inactivityTimeout中设定

                                                              vii.              ClientService都设定超时时间时,取其短

4.         Singleton

                         i.              所有的Client独立地连接到同一个Service Instance,尽管他们连接到不同的EndpointSingleton Service InstanceHost创建时创建,在Host 关闭时销毁。

                       ii.              Singleton不要求Session。当ServiceContract需要Session时,Service Instance会维护一个SessionSessionIDClient相同),当Client Proxy关闭时,Session被关闭,但Service Instance依然存在。而且Session不会过期。

                      iii.              如果想自己创建Singleton Instance并自定义初始化操作,WCF提供了一种方式:ServiceHost的一个构造函数接受Object类型的Singleton Instance,可以传递一个自己创建的对象传给ServiceHost。并且可以在Service对象的SingletonInstance属性取得此Instance。在代码链中,可以通过OperationContext.Current.Host. SingletonInstance取得。

                      iv.              Singleton十分不利于扩容性。原因是状态同步。Singleton让多个Client共享一个Service Instance,需要管理多个Client并发,状态同步,这样会降低性能。

                       v.              Singlet适用于像日志这样的只需一个对象的场景,不使用于可能服务于多个Client,并且Client可能增加的场景。

5.         Demarcating Operations

                         i.              在需要SessionServiceContract中,有时需要某个方法最先被调用,或某个方法最后被调用,WCF使用OperationContract AttributeIsInitiatingIsTerminating标识Service边界。

                       ii.              如果这两个Property被设置为非默认值,在Service Load时,WCF会检验方法所在地ServiceContract是否支持Session,如果不支持,会报异常。PerSessionSingleton都支持Demarcating Operation

6.         Instance Deactivation

                         i.              在需要SessionServiceContract中,WCF允许在某个方法上指定调用之前或之后销毁当前Service Instance

                       ii.              通过在方法上使用ReleaseInstanceMode枚举,指定行为。

                      iii.              不能在每个方法上都是用它,因为这样就和PerCall相同了。

                      iv.              可以使用Demarcating Operation指定销毁Instance的顺序。

                       v.              ReleaseInstanceMode被设为BeforCall时,方法调用前,Client被阻塞,WCF首先销毁当前Session中存在的Service Instance(调用Dispose),再调用方法。

                      vi.              ReleaseInstanceMode被设为BeforAndAfterCall时,在调用方法前后,都会销毁当前的Instance然后创建一个新的。它可以用在BeforCall之后,或AfterCall之前,用来模拟PerCall的情况。

                    vii.              除了使用Attribute在设计时指定之外,还可以调用InstanceContext.ReleaseServiceInstance()在运行时释放Service Instance。而且可以和Attribute合作,BeforCall Attribute+方法结尾时调用InstanceContext.ReleaseServiceInstance()相当于BeforAndAfterCall Attribute

                   viii.              Instance Deactivation是一个优化的技术,就像所有的优化技术一样,尽量避免把它使用到普通场景下。Instance Deactivation使用在遇到性能和可扩容性共同存在是时比较有效,并且可以得到一些改善。但如果可扩容行和吞吐量是你所关心的指标的话,尽量使用PerCall方式,而避免使用Instance Deactivation

7.         Throttling

                         i.              Throttling允许WCF抑制Client连接和负载。通过设置Throttling,可以控制Service服务的Client的数量和Service访问的资源。

                       ii.              Throttling通过把超出规定数目的Client请求入队来抑制Client的连接,如果一个Client Call在出队之前就超时的话,Client会得到超时异常。

                      iii.              Throttling使用于各种Service实例模型,即对所有的Service都有效。

                      iv.              Throttling通过Channel Dispatcher起作用

                       v.              Throttling的几种情况

1.         Session的并发数:在启用Session时,可以设置每个Session可以同时服务的Client数目,默认是10个。但这种设置对不起用Session的情况无效。

2.         调用(Call)的并发数:所有Instance服务的Client Call的并发数,默认是16个。

3.         Instance的并发数:同时存在的Instance Context的数目,默认无限制。Context的数目和Instance的数目是不一样的,取决于Instance Deactivation的设置。

4.         PerSession Service中,Instance的最大数目取决于Instance的并发数和Session的并发数。当Instance Deactivation被使用时,Instance的数目会少于Context的数目(因为Instance可能会在Call之后被销毁)。但是当Context的数目达到Instance的并发数目时,Client会被阻塞。

5.         PerCall Service中,Instance的数目就是Call的并发数。

6.         ThrottlingSingleton无效。

                      vi.              配置Throttling

1.         BehaviorsServiceBehaviorsThrottledBehavior中设置ServiceThrottlingMaxConcurrentCallsMaxConcurrentSessionsMaxConcurrentInstances

2.         编程方式:设置

host.Description.Behaviors.Find<ServiceThrottlingBehavior>( );

                    vii.              BindingThrottling

1.         可以在TCPNamePipe Binding中设置MaxConnections,如果BindingService同时设置,WCF取其最小值。

(未完待续)

posted on 2008-06-03 16:04  zhaojunqi  阅读(916)  评论(0编辑  收藏  举报

导航