PerSession与PerCall

时间:2013-02-27 05:38:06

标签: c# .net performance wcf

决定是使用PerSession还是使用PerCall的一般经验法则是什么?

我有一个稍微沉重的(我认为..)WCF服务,包含大约80个表的CRUD方法。

我已将WCF服务分为1个服务中的7个合同(即1个服务中的7个端点),这样每个合同都会处理自己的域,例如我有一个销售合同,所以所有与销售相关的表,及其相应的操作属于销售“有界背景”

所以我的WCF服务结构看起来像这样:

public partial class ABCService : ISalesService
{
   //CRUD methods of all tables related to Sales
}

public partial class ABCService : IMarketingService
{
    //CRUD methods of all tables related to Marketing
}

public partial class ABCService : ICustomerService
{
    //CRUD methods of all tables related to Customer
}

public partial class ABCService : IProductService
{
    //CRUD methods of all tables related to Products
}

我对PerCall的关注是,因为我有一个相当大的DB / WCF服务,我担心每次呼叫消耗的资源量乘以用户数量和他们称之为服务的速率,太棒了。

我不知道细节,但我已经知道创建频道代理是昂贵的操作。

哦,我正在使用手动编码代理而不是VS的添加服务引用来使用我的WCF服务。

所以,我的问题是,我该使用哪个? PerSession或PerCall?

更新

  1. 我不需要在两次通话之间保持状态。
  2. 我正在使用NetTCP绑定

2 个答案:

答案 0 :(得分:18)

在我看来,要做出决定考虑这两点

  1. InstanceContextMode.PerSession一起使用 - 如果您的用户在服务器上的WCF服务上存储了一些会话值。
  2. InstanceContextMode.PerCall一起使用 - 如果您的用户在服务器上的WCF服务上没有存储任何会话,即WCF服务要求存储在内存中不需要每个用户设置。需要可扩展性。
  3. 关于何时和为什么

    的一些观点

    InstanceContextMode.PerCall

    • 如果您的服务是无状态且可扩展的,那么好处与HTTP类似,因为它也是无状态的。
    • 如果服务具有轻量级初始化代码(或根本没有)。
    • 如果您的服务是单线程的。
    • 示例方案:对于PerCall情况下给定时间段内的任何1000个客户端请求,只有100个对象实例化为100个活动调用。其次,如果服务器崩溃,那么在PerCall情况下,唯一会发生的错误将是100个正在进行的实际请求(假设快速故障转移)。其他900个客户端可以在下一次呼叫时路由到另一台服务器。

    InstanceContextMode.PerSession

    • 如果您的服务必须在来自同一客户端的呼叫之间保持某种状态。
    • 如果您的服务具有轻量级初始化代码(或根本没有)。即使您只为每个客户端代理获取一个新实例,您仍然需要注意在构造函数中使用昂贵的初始化代码。
    • 示例方案:对于PerSession情况下给定时间段内的任何1000个客户端请求,您可能在服务器上实例化了1000个对象,但实际上只有100个活动< / strong>随时待命。因此,实例化的PerSession对象可能浪费资源,并可能影响在负载下处理请求的能力。其次,如果服务器崩溃,那么在PerSession中,在该服务器上拥有会话的所有1000个客户端将丢失其会话并且无法完成其工作。

    参考链接:

    1. MSDN - WCF Instancing, Concurrency, and Throttling
    2. SO - Per-Call vs Per-Session
    3. MSDN - Using Sessions in WCF context

答案 1 :(得分:1)

您在网上看不到这类问题的答案的原因是它取决于。我要做的就是尝试一下 - 然后在你托管服务的服务器上打开perfmon,并为你的服务添加计数器。如果你不熟悉,只需google wcf性能经理专柜。

好消息是WCF使设置变得非常简单。

如果您担心在客户端实例化代理的成本,请记住perCall是服务行为,而不是客户端行为。即使您将服务实例上下文设置为PerCall,您仍然可以创建一个代理实例并从该代理进行一系列方法调用。所有perCall意味着当您拨打电话时,会创建服务实例,调用您的方法,并再次拆除服务实例。如果您没有在服务实例上进行任何昂贵的初始化(即,如果它们基本上是静态方法),那么每次调用都可能没问题。