实例模型(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服务时需要注意 |
- 注意会话所带来的开销和潜在的超时问题 |
• 通常要避免使用单件模型 |
- 当多台客户端主机共享某个功能的时候非常有用 |
|