|
实例模型(Instancing Modes) |
|
|
|
|
|
我们将涉及到… |
|
• 可用于WCF服务的实例模型 • 无状态与有状态的服务 |
|
• 会话(Session)服务的需求与注意事项 • 单件服务的正确使用方法 |
|
• 实例模型对于资源分配 , 可扩展性和并发性的 影响 |
|
课程准备 |
|
• 拥有构建Microsoft® .NET Framework应用 程序的经验 |
|
• 基本理解WCF客户端与服务,数据契约与 服务契约 |
|
|
|
议题 |
|
• 实例模型的配置 • Per call服务 • Per session服务 • 单件服务 |
|
调用场景 |
|
• 经典的客户端/服务器(C/S)应用程序 |
|
- 客户端使用远程,有状态的对象并且在其生命周期 内进行控制 |
|
• 分布式 , 可扩展的应用程序 |
|
- 通过及时释放远程对象来节约资源的使用 |
|
• 分布式单件 |
|
- 多个客户端共享状态 |
|
• 经典的无状态Web服务调用 |
|
实例模型 |
|
• 控制服务实例的生命周期 • InstanceContextMode枚举 |
|
- PerCall |
|
- PerSession - Single |
|
• ServiceBehaviorAttribute控制这个设置 |
|
PerCall模式 |
|
• 为每个调用创建新的服务对象
|
|
Client |
|
Proxy |
|
Proxy |
|
Service |
|
Service |
|
Service |
|
|

|
PerCall模式 |
|
• PerCall服务增加了整体的吞吐量 |
|
- 状态不会在多次调用中存在 |
|
Client |
|
Client |
|
- 服务实例被释放 |
|
- 内存开销较小 |
|
Proxy |
|
Proxy |
|
– 不会产生并发性问题 |
|
Service |
|
Service |
|
Service |
|
Service |
|
PerCall体系结构 |
|
Client |
|
Client |
|
• 无状态调用 |
|
Proxy |
|
Proxy |
|
• 为每个请求分别实例化业 |
|
务逻辑和数据层 |
|
• 不存在并发性问题 |
|
Service |
|
Service |
|
Service |
|
Service |
|
Business |
|
Business |
|
Business |
|
Business |
|
Data |
|
Data |
|
Data |
|
Data |
|
PerCall体系结构 |
|
• 无状态调用可以共享缓 |
|
Client |
|
Client |
|
存的内容 |
|
• 引入并发性问题以及资 |
|
Proxy |
|
Proxy |
|
源占用的问题 |
|
Service |
|
Service |
|
Service |
|
Service |
|
Cache |
|
配置PerCall |
|
• InstanceContextMode.PerCall |
|
[ServiceBehavior(InstanceContextMode= InstanceContextMode.PerCall)] public class |
|
CounterServicePerCall:ICounterServicePerCall |
|
PerCall服务 |
|
会话(Session) |
|
• WCF有四种类型的会话: |
|
- 传输会话,如:TCP或者命名管道(named pipe) - 可靠性会话 |
|
安全会话 |
|
- 应用程序会话 |
|
• 应用程序会话是我们这次讨论的主题 • WCF的会话由客户端发起 |
|
- ASP.NET的会话由服务器端初始化 |
|
PerSession模式 |
|
• 为每个客户端/代理创建新的服务对象 |
|
- 缺省行为 |
|
Client |
|
Client |
|
• 吞吐量较少,内存开销增大 |
|
• 状态由服务实例维护 |
|
Proxy |
|
Proxy |
|
• 引发多线程客户端的并发 |
|
问题 |
|
Service |
|
Service |
|
PerSession体系结构 |
|
Client |
|
Client |
|
• 有状态调用 |
|
Proxy |
|
Proxy |
|
• 每个会话可以缓存下游的 业务逻辑和数据层 |
|
• 多线程客户端及其之间存 在并发性问题 |
|
Service |
|
State |
|
Service |
|
State |
|
• 状态与会话紧密联系,而 |
|
Business |
|
Business |
|
Business |
|
Business |
|
不是业务逻辑层 |
|
Data |
|
Data |
|
Data |
|
Data |
|
PerSession模式 |
|
• 仅当绑定支持会话时,才能够支持会话 |
|
• 可以支持会话的绑定: |
|
Client |
|
Client |
|
- NetTcpBinding |
|
– NetNamedPipeBinding |
|
Proxy |
|
Proxy |
|
- WSHttpBinding |
|
– WSFederationHttpBinding |
|
- WSDualHttpBinding |
|
Service |
|
Service |
|
配置PerSession |
|
• InstanceContextMode.PerSession |
|
- 缺省设置 |
|
- 最好能够显式指定 |
|
[ServiceBehavior(InstanceContextMode= InstanceContextMode.PerSession)] public class |
|
CounterServicePerSession:ICounterServicePerSession |
|
配置会话 |
|
• 在服务契约上需要设置能够提供会话功能 • SessionMode 枚举: |
|
- Allowed (缺省) |
|
- NotAllowed |
|
- Required |
|
配置会话 |
|
[ServiceContract(Namespace= |
|
"http://www.thatindigogirl.com/samples/2006/06", SessionMode=SessionMode.Required)] |
|
public interface ICounterServiceSession { |
|
[OperationContract] int IncrementCounter(); } |
|
PerSession服务 |
|
会话ID(Session Id) |
|
• 任何形式的会话都会生成会话信道 • 会话标示符用于将消息与正确的信道相关联 |
|
- 在会话的整个生命周期中起作用 |
|
• SessionId信道的属性 |
|
SessionServiceClient proxy=new SessionServiceClient (); string s = proxy.InnerChannel.SessionId; |
|
会话的生命周期 |
|
• 会话的生命周期缺省为持续10分钟 • 在每个绑定上可以通过receiveTimeout 设 置进行控制 |
|
<n etTc pBinding > |
|
<binding name="netTcp" receiveTimeout="00:10:00" /> </netTcpBinding> |
|
会话的生命周期 |
|
• 可以通过操作显式地控制生命周期 • 设置OperationContractAttribute的 IsInitiating 与 IsTerminating属性 |
|
会话的生命周期 |
|
[ServiceContract(Namespace = |
|
"http://www.thatindigogirl.com/samples/2006/06", SessionMode = SessionMode.Required)] public interface ISessionService { |
|
[OperationContract(IsInitiating = true IsTerminating = false)] |
|
void StartSession(); |
|
[OperationContract(IsInitiating = false, IsTerminating = false)] |
|
void IncrementCounter(); |
|
[OperationContract(IsInitiating = false, IsTerminating = false)] |
|
int GetCounter(); |
|
[OperationContract(IsInitiating = false, IsTerminating = false)] |
|
string GetSessionId(); |
|
[OperationContract(IsInitiating = false, IsTerminating = true)] |
|
void StopSession(); |
|
} |
|
会话的生命周期 |
|
单件模式 |
|
• 为所有客户端的所有调用创建单一的服务对象 |
|
- 称之为单件服务 |
|
Client |
|
Client |
|
• 通常会给吞吐量带来 |
|
负面影响 |
|
Proxy |
|
Proxy |
|
• 潜在的较多内存开销 |
|
– 单一的大对象 |
|
• 状态由服务的实例维护 • 并发性问题 |
|
Service |
|
配置单件 |
|
• InstanceContextMode.Single |
|
[ServiceBehavior(InstanceContextMode= InstanceContextMode.Single)] |
|
public class CounterServiceSingle:ICounterServiceSingle |
|
单件的体系结构 |
|
Client |
|
Client |
|
• 无状态单件 |
|
Proxy |
|
Proxy |
|
• 下游业务逻辑和数据层能 够被所有的请求共享 |
|
- 它们通常都是无状态的 |
|
• 并发调用会引发并发性问 |
|
Service |
|
题 |
|
Business |
|
Data |
|
单件的体系结构 |
|
Client |
|
Client |
|
• 单件也可以是有状态的 |
|
Proxy |
|
Proxy |
|
• 特别在处理无状态的业务 逻辑对象时 |
|
• 状态由服务的会话ID( SessionId)跟踪 |
|
Service |
|
State |
|
– 只有一个单件的对象 |
|
Business |
|
Business |
|
Business |
|
Business |
|
Data |
|
Data |
|
Data |
|
Data |
|
单件服务 |
|
会话总结 |
|
• PerCall适用于 |
|
- 用于高可扩展性和高吞吐量的业务 |
|
• 使用PerSession服务时需要注意 |
|
- 注意会话所带来的开销和潜在的超时问题 |
|
• 通常要避免使用单件模型 |
|
- 当多台客户端主机共享某个功能的时候非常有用 |
|
|

浙公网安备 33010602011771号